The aim of this tutorial is to create import/export lists. The frame should display two lists with the abitlity to exchange items between the two lists. It should also be possible to delete items from one list or the other. Such a window usually looks like the one below. The selected items are sent to the other list using the < or > buttons. The Delete buttons delete the currently selected items in the current list.
As usual, the code is reproduced at the end of this page; it can also be downloaded here.
First, let's have a look at the widget layout. We'll use a FormContainer and a ColumnContainer. The FormContainer will define a 3x3 grid as shown below :
BLabel "List 1" | BLabel "List 2" | |||
BList list 1 (embedded in a BScrollPane) | ColumnContainer:
|
BList list 2 (embedded in a BScrollPane) | ||
BButton Delete | BButton Delete |
There is nothing much to say about this layout, except that:
buttonsCc.add( importButtons[0], new LayoutInfo(
LayoutInfo.SOUTH, LayoutInfo.NONE, new Insets( 5, 5, 5, 5), null )
);
buttonsCc.add( importButtons[1], new LayoutInfo(
LayoutInfo.NORTH, LayoutInfo.NONE, new Insets( 5, 5, 5, 5 ), null ) );
BScrollPane[] scrollPanes = new
BScrollPane[2];
for ( int i = 0; i < 2; ++i
)
{
scrollPanes[i] = new BScrollPane( lists[i]
);
scrollPanes[i].setForceWidth( true );
}
LayoutInfo listLayout = new LayoutInfo(
LayoutInfo.CENTER, LayoutInfo.BOTH, new Insets( 5, 5, 5, 5 ), null
);
FormContainer fc = new FormContainer( 3, 3 );
fc.add(
scrollPanes[0], 0, 1, listLayout );
fc.add( scrollPanes[1], 2, 1,
listLayout );
Apart from illustrating the use of the BList widget, this tutorials
also shows how to deal with events and widget arrays. In this example, the
two lists are addressed as a BList array, as well as the export BButtons.
The same method is link to any event type considered, e.g. doExchange is
linked to both export buttons. In that case, it can be useful to specify
the event object as a parameter to the method the event is linked to, so
that the event source can be identified. There are, however, some cases
where there is no need to know which widget generated the event, like for
doSelect()
, to which both lists are linked.
It is high time we define the (bare) functionalities of the sample app:
The selection business is addressed through linking the
SelectionChangedEvent event of both BLists to the doSelect()
method. The lists are then asked for selection (
getSelectedValues()
) and the buttons are disabled or enabled
accordingly. This method is rough, since it doesn't take into account
which BList has generated the event. Writing this tutorial, I realize that
I forgot to enable/disable the export buttons : I guess that's your
homework ;-).
The Delete buttons CommandEvent events are linked to
doDelete(CommandEvent evt)
, which identifies the index of the
button that generated the event and deletes the selection from the
relevant list. BList.getSelectedIndices()
gives the indices
of the items to delete, which are deleted in reverse order. The Delete
button is then disabled since the selection is now empty.
int which = ( evt.getWidget() == deleteButtons[0] ? 0 : 1 ); int[] selection = lists[which].getSelectedIndices(); if ( selection != null ) { for ( int i = selection.length - 1; i >= 0; --i ) { lists[which].remove( selection[i] ); } deleteButtons[which].setEnabled( false ); }
The export buttons also generate a CommandEvent which is this time
connected to the doExchange(CommandEvent evt)
. The source of
the event is identified as before. The selection of the from list is added
to the destination list. A following doDelete(evt)
call could
cut the selected items if the functionalities of the application asked for
it.
int from = ( evt.getWidget() == importButtons[0] ? 0 : 1 ); int to = 1 - from; Object[] selection = null; if ( lists[from].getSelectedIndex() >= 0 ) selection = lists[from].getSelectedValues(); if ( selection != null ) { for ( int i = 0; i < selection.length; ++i ) { lists[to].add( selection[i] ); } }
The full source code is given below:
import java.awt.*; import buoy.event.*; import buoy.widget.*; /** * BList demo * *@author François Guillet *@created 2004/05/28 */ public class BListDemo extends BFrame { BList[] lists; BButton[] importButtons; BButton[] deleteButtons; /** * Constructor for the BListDemo object */ public BListDemo() { super( "BListDemo" ); BorderContainer border = new BorderContainer(); setContent( border ); importButtons = new BButton[2]; importButtons[0] = new BButton( ">" ); importButtons[1] = new BButton( "<" ); ColumnContainer buttonsCc = new ColumnContainer(); buttonsCc.add( importButtons[0], new LayoutInfo( LayoutInfo.SOUTH, LayoutInfo.NONE, new Insets( 5, 5, 5, 5 ), null ) ); buttonsCc.add( importButtons[1], new LayoutInfo( LayoutInfo.NORTH, LayoutInfo.NONE, new Insets( 5, 5, 5, 5 ), null ) ); LayoutInfo layout = new LayoutInfo( LayoutInfo.CENTER, LayoutInfo.NONE, new Insets( 5, 5, 5, 5 ), null ); for ( int i = 0; i < 2; ++i ) importButtons[i].addEventLink( CommandEvent.class, this, "doExchange" ); lists = new BList[2]; lists[0] = new BList( new String[]{"1", "2", "3"} ); lists[1] = new BList( new String[]{"one", "two", "three"} ); BScrollPane[] scrollPanes = new BScrollPane[2]; for ( int i = 0; i < 2; ++i ) { scrollPanes[i] = new BScrollPane( lists[i] ); scrollPanes[i].setForceWidth( true ); } LayoutInfo listLayout = new LayoutInfo( LayoutInfo.CENTER, LayoutInfo.BOTH, new Insets( 5, 5, 5, 5 ), null ); FormContainer fc = new FormContainer( 3, 3 ); fc.add( new BLabel( "list 1" ), 0, 0, layout ); fc.add( new BLabel( "list 2" ), 2, 0, layout ); fc.add( scrollPanes[0], 0, 1, listLayout ); fc.add( buttonsCc, 1, 1, layout ); fc.add( scrollPanes[1], 2, 1, listLayout ); deleteButtons = new BButton[2]; deleteButtons[0] = new BButton( "Delete" ); deleteButtons[1] = new BButton( "Delete" ); for ( int i = 0; i < 2; ++i ) deleteButtons[i].addEventLink( CommandEvent.class, this, "doDelete" ); fc.add( deleteButtons[0], 0, 2, layout ); fc.add( deleteButtons[1], 2, 2, layout ); setContent( fc ); addEventLink( WindowClosingEvent.class, this, "doQuit" ); for ( int i = 0; i < 2; ++i ) { lists[i].addEventLink( SelectionChangedEvent.class, this, "doSelect" ); deleteButtons[i].setEnabled( false ); } pack(); setVisible( true ); } /** * Quit */ private void doQuit() { System.exit( 0 ); } /** * Exchange items from one list to another * *@param evt The command event */ private void doExchange( CommandEvent evt ) { int from = ( evt.getWidget() == importButtons[0] ? 0 : 1 ); int to = 1 - from; Object[] selection = null; if ( lists[from].getSelectedIndex() >= 0 ) selection = lists[from].getSelectedValues(); if ( selection != null ) { for ( int i = 0; i < selection.length; ++i ) { lists[to].add( selection[i] ); } } } /** * Delete items * *@param evt The command event */ private void doDelete( CommandEvent evt ) { int which = ( evt.getWidget() == deleteButtons[0] ? 0 : 1 ); int[] selection = lists[which].getSelectedIndices(); if ( selection != null ) { for ( int i = selection.length - 1; i >= 0; --i ) { lists[which].remove( selection[i] ); } deleteButtons[which].setEnabled( false ); } } /** * What to do when an item is selected */ private void doSelect() { for ( int i = 0; i < 2; ++i ) { if ( lists[i].getSelectedIndex() >= 0 ) deleteButtons[i].setEnabled( true ); else deleteButtons[i].setEnabled( false ); } } /** * Main * *@param args The command line arguments */ public static void main( String[] args ) { new BListDemo(); } }