Pick Me
Contents:
Choice
Lists
Checkbox
CheckboxGroup
ItemSelectable
Three AWT components let you present a list of choices to users: Choice
, List
, and Checkbox
. All three components implement the ItemSelectable
interface ( Java1.1). These components are comparable to selection mechanisms in modern GUIs so most readers will be able to learn them easily, but I'll point out some special enhancements that they provide.
Choice
and List
are similar; both offer a list of choices for the user to select. Choice
provides a pull-down list that offers one selection at a time, whereas List
is a scrollable list that allows a user to make one or multiple selections. From a design standpoint, which you choose depends at least partially on screen real estate; if you want the user to select from a large group of alternatives, Choice
requires the least space, List
requires somewhat more, while Checkbox
requires the most. Choice
is the only component in this group that does not allow multiple selections. A List
allows multiple or single selection; because each Checkbox
is a separate component, checkboxes inherently allow multiple selection. In order to create a list of mutually exclusive checkboxes, in which only one box can be selected at a time (commonly known as radio buttons), you can put several checkboxes together into a CheckboxGroup
, which is discussed at the end of this chapter.
Choice
The Choice
component provides pop-up/pull-down lists. It is the equivalent of Motif's OptionMenu or Windows MFC's ComboBox. ( Java 1.1 departs from the MFC world.) With the Choice
component, you can provide a short list of choices to the user, while taking up the space of a single item on the screen. When the component is selected, the complete list of available choices appears on the screen. After the user has selected an option, the list is removed from the screen and the selected item is displayed. Selecting any item automatically deselects the previous selection.
Component Methods
Constructors- public Choice ()
- There is only one constructor for
Choice
. When you call it, a new instance ofChoice
is created. The component is initially empty, with no items to select. Once you add some items usingaddItem()
(version 1.0) oradd()
(version 1.1) and display theChoice
on the screen, it will look something like the leftmost component in Figure 9.1. The center component shows what aChoice
looks like when it is selected, while the one on the right shows what aChoice
looks like before any items have been added to it.
Figure 9.1: How Choices are displayed
Items
- public int getItemCount ()
public int countItems () - The
getItemCount()
method returns the number of selectable items in theChoice
object. In Figure 9.1,getItemCount()
would return 6.countItems()
is the Java 1.0 name for this method. - public String getItem (int index)
- The
getItem()
method returns the text for the item at positionindex
in theChoice
. Ifindex
is invalid--eitherindex
< 0 orindex
>=getItemCount()
--thegetItem()
method throws theArrayIndexOutOfBoundsException
run-time exception. - public synchronized void add (String item)
public synchronized void addItem (String item) add()
addsitem
to the list of available choices. Ifitem
is already an option in theChoice
, this method adds it again. Ifitem
isnull
,add()
throws the run-time exceptionNullPointerException
. The firstitem
added to aChoice
becomes the initial (default) selection.addItem()
is the Java 1.0 name for this method.- public synchronized void insert (String item, int index)
insert()
addsitem
to the list of available choices at positionindex
. An index of 0 adds the item at the beginning. An index larger than the number of choices adds the item at the end. Ifitem
isnull
,insert()
throws the run-time exceptionNullPointerException
. Ifindex
is negative,insert()
throws the run-time exceptionIllegalArgumentException
.- public synchronized void remove (String item)
remove()
removesitem
from the list of available choices. Ifitem
is present inChoice
multiple times, a call toremove()
removes the first instance. Ifitem
isnull
,remove()
throws the run-time exceptionNullPointerException
. Ifitem
is not found in theChoice
,remove()
throws theIllegalArgumentException
run-time exception.- public synchronized void remove (int position)
remove()
removes the item atposition
from the list of available choices. Ifposition
is invalid--eitherposition
< 0 orposition
>=getItemCount()
--remove()
throws the run-time exceptionArrayIndexOutOfBoundsException
.- public synchronized void removeAll ()
- The
removeAll()
method removes every option from theChoice
. This allows you to refresh the list from scratch, rather than creating a newChoice
and repopulating it.
The Choice
has one item selected at a time. Initially, it is the first item that was added to the Choice
.
- public String getSelectedItem ()
- The
getSelectedItem()
method returns the currently selected item as aString
. The text returned is the parameter used in theaddItem()
oradd()
call that put the option in theChoice
. IfChoice
is empty,getSelectedItem()
returnsnull
. - public Object[] getSelectedObjects ()
- The
getSelectedObjects()
method returns the currently selected item as anObject
array, instead of aString
. The array will either be a one-element array, ornull
if there are no items. This method is required by theItemSelectable
interface and allows you to use the same method to look at the items selected by aChoice
,List
, orCheckbox
. - public int getSelectedIndex ()
- The
getSelectedIndex()
method returns the position of the currently selected item. TheChoice
list uses zero-based indexing, so the position of the first item is zero. The position of the last item is the value ofcountItems()-1
. If the list is empty, this method returns -1. - public synchronized void select (int position)
- This version of the
select()
method makes the item atposition
the selected item in theChoice
. Ifposition
is too big,select()
throws the run-time exceptionIllegalArgumentException
. Ifposition
is negative, nothing happens. - public void select (String string)
- This version of
select()
makes the item with the labelstring
the selected item. Ifstring
is in theChoice
multiple times, this method selects the first. Ifstring
is not in theChoice
, nothing happens.
- public synchronized void addNotify ()
- The
addNotify()
method creates theChoice
's peer. If you override this method, callsuper.addNotify()
first, then add your customizations for the new class. You will then be able to do everything you need with the information about the newly created peer. - protected String paramString ()
- When you call the
toString()
method of aChoice
, the defaulttoString()
method ofComponent
gets called. This in turn callsparamString()
which builds up the string to display. At theChoice
level,paramString()
appends the currently selected item (the result ofgetSelectedItem()
) to the output. Using the firstChoice
instance in Figure 9.1, the results would be:
java.awt.Choice[139,5,92x27,current=Dialog]
Choice Events
The primary event for a Choice
occurs when the user selects an item in the list. With the 1.0 event model, selecting an item generates an ACTION_EVENT
, which triggers a call to the action()
method. Once the Choice
has the input focus, the user can change the selection by using the arrow or keyboard keys. The arrow keys scroll through the list of choices, triggering the KEY_ACTION
, ACTION_EVENT
, and KEY_ACTION_RELEASE
event sequence, which in turn invokes the keyDown()
, action()
, and keyUp()
methods, respectively. If the mouse is used to choose an item, no mouse events are triggered as you scroll over each item, and an ACTION_EVENT
occurs only when a specific choice is selected.
With the 1.1 event model, you register ItemListener
with addItemListener()
. Then when the user selects the Choice
, the ItemListener.itemStateChanged()
method is called through the protected Choice.processItemEvent()
method. Key, mouse, and focus listeners are registered through the Component
methods of addKeyListener()
, addMouseListener()
, and addFocusListener()
, respectively. Action
- public boolean action (Event e, Object o)
- The
action()
method for a choice signifies that the user selected an item.e
is theEvent
instance for the specific event, whileo
is theString
from the call toaddItem()
oradd()
that represents the current selection. Here's a trivial implementation of the method:
public boolean action (Event e, Object o) { if (e.target instanceof Choice) { System.out.println ("Choice is now set to " + o); } return false; }Keyboard
The keyboard events for a Choice
can be generated once the Choice
has the input focus. In addition to the KEY_ACTION
and KEY_ACTION_RELEASE
events you get with the arrow keys, an ACTION_EVENT
is generated over each entry.
- public boolean keyDown (Event e, int key)
- The
keyDown()
method is called whenever the user presses a key and theChoice
has the input focus.e
is theEvent
instance for the specific event, whilekey
is the integer representation of the character pressed. The identifier for the event (e.id
) forkeyDown()
could be eitherEvent.KEY_PRESS
for a regular key orEvent.KEY_ACTION
for an action-oriented key (i.e., arrow or function key). If you check the current selection in this method through the methodgetSelectedItem()
orgetSelectedIndex()
, you will be given the previously selected item because theChoice
's selection has not changed yet.keyDown()
is not called when theChoice
is changed by using the mouse. - public boolean keyUp (Event e, int key)
- The
keyUp()
method is called whenever the user releases a key.e
is theEvent
instance for the specific event, whilekey
is the integer representation of the character pressed. The identifier for the event (e.id
) forkeyUp()
could be eitherKEY_RELEASE
for a regular key orKEY_ACTION_RELEASE
for an action oriented key (i.e., arrow or function key).
Ordinarily, the Choice
component does not trigger any mouse events. Focus
Ordinarily, the Choice
component does not trigger any focus events. Listeners and 1.1 event handling
With the 1.1 event model, you register listeners for different event types; the listeners are told when the event happens. These methods register listeners, and let the Choice
component inspect its own events.
- public void addItemListener(ItemListener listener)
- The
addItemListener()
method registerslistener
as an object interested in being notified when anItemEvent
passes through theEventQueue
with thisChoice
as its target. Thelistener.itemStateChanged()
method is called when an event occurs. Multiple listeners can be registered. - public void removeItemListener(ItemListener listener)
- The
removeItemListener()
method removeslistener
as a interested listener. Iflistener
is not registered, nothing happens. - protected void processEvent(AWTEvent e)
- The
processEvent()
method receives allAWTEvent
s with thisChoice
as its target.processEvent()
then passes them along to any listeners for processing. When you subclassChoice
, overridingprocessEvent()
allows you to process all events yourself, before sending them to any listeners. In a way, overridingprocessEvent()
is like overridinghandleEvent()
using the 1.0 event model.If you override
processEvent()
, remember to callsuper.processEvent(e)
last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to callenableEvents()
(inherited fromComponent
) to ensure that events are delivered even in the absence of registered listeners. - protected void processItemEvent(ItemEvent e)
- The
processItemEvent()
method receives allItemEvent
s with thisChoice
as its target.processItemEvent()
then passes them along to any listeners for processing. When you subclassChoice
, overridingprocessItemEvent()
allows you to process all events yourself, before sending them to any listeners. In a way, overridingprocessItemEvent()
is like overridinghandleEvent()
using the 1.0 event model.If you override
processItemEvent()
, remember to call the methodsuper.processItemEvent(e)
last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to callenableEvents()
(inherited fromComponent
) to ensure that events are delivered even in the absence of registered listeners.
The following simple applet below demonstrates how a component can receive its own events by overriding processItemEvent()
, while still allowing other objects to register as listeners. MyChoice11
is a subclass of Choice
that processes its own item events. choice11
is an applet that uses the MyChoice11
component and registers itself as a listener for item events.
// Java 1.1 only import java.awt.*; import java.applet.*; import java.awt.event.*; class MyChoice11 extends Choice { MyChoice11 () { super (); enableEvents (AWTEvent.ITEM_EVENT_MASK); } protected void processItemEvent(ItemEvent e) { ItemSelectable ie = e.getItemSelectable(); System.out.println ("Item Selected: " + ie.getSelectedObjects()[0]); // If you do not call super.processItemEvent() // no listener will be notified super.processItemEvent (e); } } public class choice11 extends Applet implements ItemListener { Choice c; public void init () { String []fonts; fonts = Toolkit.getDefaultToolkit().getFontList(); c = new MyChoice11(); for (int i = 0; i < fonts.length; i++) { c.add (fonts[i]); } add (c); c.addItemListener (this); } public void itemStateChanged(ItemEvent e) { ItemSelectable ie = e.getItemSelectable(); System.out.println ("State Change: " + ie.getSelectedObjects()[0]); } }
A few things are worth noticing. MyChoice11
calls enableEvents()
in its constructor to make sure that item events are delivered, even if nobody registers as a listener: MyChoice11
needs to make sure that it receives events, even in the absence of listeners. Its processItemEvent()
method ends by calling the superclass's processItemEvent()
method, with the original item event. This call ensures that normal item event processing occurs; super.processItemEvent()
is responsible for distributing the event to any registered listeners. The alternative would be to implement the whole registration and event distribution mechanism inside myChoice11
, which is precisely what object-oriented developing is supposed to avoid, or being absolutely sure that you will only use MyChoice11
in situations in which there won't be any listeners, drastically limiting the usefulness of this class.
choice11
doesn't contain many surprises. It implements ItemListener
, the listener interface for item events; provides the required itemStateChanged()
method, which is called whenever an item event occurs; and calls MyChoice11
's method addItemListener()
to register as a listener for item events. (MyChoice11
inherits this method from the Choice
class.)