User Interfaces
Homework #3
Due March 26
Total points: 14
Submit to Ting-jen Yen

Write a Java class called Accumulator that allows the user to select items from a list by placing them into a second list. Your widget should look like this:

Selecting an item in the left list and clicking on the ">>" button copies that item into the right list. A selection can be undone by clicking on the item in the right list and then clicking on the "<<" button. A more precise description is given below.

Programming Interface

Your class must conform to the following precisely so that we can test it easily. Homework failing to conform to this interface will receive a zero.

 The class must be named Accumulator.

 The class must implement the ItemSelectable interface.

Accumulator(String leftLabel, String rightLabel, int lines, boolean allowDuplicates)
The first two parameters to this constructor are the labels that appear above the left and right lists, respectively. The third parameter specifies the number of lines that each list contains on the screen (the same as the first parameter to the List constructor). The fourth parameter specifies whether the user can accumulate multiple copies of the same item. (This will be explained in more detail below.) Note that this is not the same as the second argument to the List constructor.

 void addItem(String item)
Adds one copy of the item to the left list.

void removeItem(String item)
Completely removes the item for both lists. (If there are multiple copies of the item, removes them all.)

String[] getSelectedItems()
Returns the items in the right list, in the order they appear. Multiple items will appear multiple times in the array. For instance, if the right list has three copies of the item "Arizona", the list will display that as "Arizona (3)" but the array returned by this method will have three consecutive copies of the string "Arizona".

Object[] getSelectedObjects()
Equivalent to the above; required by the ItemSelectable interface.

void addItemListener(ItemListener l)
Adds an ItemListener to the object.

void removeItemListener(ItemListener l)
Removes the ItemListener from the object, if it is present.

You are also required to use only a GridBagLayout for layout management. Do not use any other layout managers, or any graphical design tools.


Here is the rest of specification. Each item is proceeded by how many points it is worth.

  1. (3) Duplicate the layout shown above. In particular, the two buttons should appear next to each other and centered vertically with respect to the lists. (I suggest you make your class inherit from Panel. You can achieve the layout using a GridBagLayout with three rows and three columns.)
  2. (2) The resize behavior should be as shown: the lists should change size, but the buttons and labels should not. (This can be done by setting the weights correctly.)
  3. (0.5) Both lists should allow multiple selections (the second constructor parameter should be true).
  4. (0.5) Only one list at a time should have selected items. Clicking on the other list should deselect everything in the first list.
  5. (0.5) A button should only be enabled when there is a selection in the corresponding list. For instance, the >> button should be disabled when nothing in the left list is selected.
  6. (2) If either list has multiple copies of an item, then the list should use a single line for that item, with a number in parentheses indicating the number of copies. For instance, one copy of "Idaho" would display as "Idaho", but five copies would display as "Idaho (5)". (Suggestion: I found it helpful to write a subclass of List which I called MultiList. It kept track of the multiplicity of each item and handled the display. Be careful if you do this not to override the getItem method.)
  7. (2) If duplicates are not allowed (the fourth argument to the constructor is false), then the >> button has the following effect: for each selected item in the left list, one copy of the item is removed from the left list and inserted into the right list. If an item already appears in the right list, the count of that item is increased. If it item doesn't appear, it is appended to the end of the list. Items are appended to the right list in the same order that they appear in the left list. Any items not completely removed from the left list remain selected. For example, if the selected items of the left list are "Arizona", "Colorado (2)" and "Kentucky" and the right list consists only of "Kentucky", then after the button is pushed "Arizona" and "Kentucky" are removed from the left list while "Colorado" remains (without a number) and is selected, while the right list displays, from top to bottom, "Kentucky (2)", "Arizona" and "Colorado".
  8. (1.5) If duplicates are not allowed, then the << button has the same effect as above, except (a) the items are removed from the right list and inserted into the left list, and (b) the items are restored to their original positions in the left list, even if they had been completely removed. (I found this easier to program if the left MultiList did not delete items with a zero count from its internal data structure. The right MultiList, on the other hand, should delete such items.)
  9. (0.5) If duplicates are allowed, then the behavior of the buttons is the same except that no items are ever removed from or added to the left list.
  10. (0.5) Double-clicking on any list item is identical to single-clicking on the item, and then pressing the appropriate button.
  11. (1) An Accumulator's ItemListeners are notified each time an item is added to or removed from the right list. In both cases, create an ItemEvent object and call each listener's itemStateChanged method on the object. The ItemEvent constructor takes four parameters: the Accumulator object itself, the constant ItemEvent.ITEM_STATE_CHANGED, the item added or removed, and one of the constants ItemEvent.SELECTED (if added) or ItemEvent.DESELECTED (if removed). You should create a separate event for each item that is added; thus a single button click may generate many events, if there are multiple selections.

 That concludes the list of things that you have to worry about. You don't have to worry about the exact spacing between components in the layout (e.g. I've put 2 pixels around each button, but you don't have to), or the quirks of how Java lists do multiple selection (they don't conform to Windows standards, for instance).


Submit your solution by mailing a single file with your source code to the TA mentioned above.