Handling Events in Java GUI Programs
A JCheckBox has two states, selected and unselected, and the state is represented by a boolean that is true when selected and false when unselected.
Reducing a Checkbox to One Boolean
A checkbox on a screen can look like many things, but a Java program does not need to track its appearance. A JCheckBox has two states, selected and unselected, and the state is represented by a boolean that is true when the box is selected and false when it is unselected. Everything else in this article, including setting the state, reading it, and reacting to changes, is built on that one boolean.
The article follows a short program rather than starting from definitions. A checkbox is created, its state is changed in code, and the state is read back. As you trace the run, keep one question in mind: at which step does the reported result first differ from what you expected? Locating that exact step is the core debugging skill for any GUI component. A state value that looks wrong is usually the result of one specific call or one specific event, not of the whole program.
What do you think happens?
If a program calls setSelected(true) on a checkbox, does the checkbox fire an ActionEvent?
Reveal answer
No, setSelected() generates no event
A user click generates an ActionEvent. Calling setSelected() changes the state without generating one. Only the user's interaction, or a call to doClick(), produces an event.
Giving a Checkbox Its Label
A checkbox has a label, and the label is specified at the moment the box is constructed. The label is passed as a string argument to the JCheckBox constructor. The variable name is only a name for the Java object in your code; the string argument is what the user sees next to the box.
showTimeis the Java variable name that refers to the checkbox object- "Show Current Time" is the string label that appears on screen
- The label is supplied in the constructor call, at construction time
Tracing the State Through a Run
The user can change the state of a JCheckBox by clicking it, and the program can change it too. Each state move flips the boolean that the checkbox holds. The diagram below shows the two states and the two ways the state can move between them. In this trace we assume the box begins in the unselected state.
Two methods control the state from code. The setSelected(boolean) method sets the current state: passing true selects the box and passing false clears it. The isSelected() method reports the current state as a boolean. In many programs this is all you need. Your code does not have to react at the instant the box changes; it can simply call isSelected() whenever it needs to know the state, for example when a Save button is pressed.
before: false
after: trueisSelected()is read before any change, so it reports the starting unselected statesetSelected(true)changes the state in codeisSelected()is read again and now returns true
Reading the state at each step
A program creates a checkbox labeled Show Current Time, calls setSelected(true), then calls setSelected(false). What does isSelected() report after each call, starting from the unselected state?
- 1Start
The box begins unselected, so its boolean state is false.
- 2After setSelected(true)
The state moves to selected.
isSelected()returns true. - 3After setSelected(false)
The state moves back to unselected.
isSelected()returns false.
The reported values are false, true, false. Each call moves the single boolean, and isSelected() simply reads it.
Why a Click Fires an Event and a Call Does Not
A checkbox generates an event of type ActionEvent when its state is changed by the user. Calling setSelected() does not generate an ActionEvent. The method doClick() is different: it simulates a user click on the checkbox and does generate an ActionEvent. If you want something to happen at the moment the user changes the state, you must register an ActionListener with the checkbox by calling addActionListener(). The listener's actionPerformed() method then receives an event object each time the user changes the box.
Identifying the Source of an Event
A single listener can serve several checkboxes. When a handler receives an ActionEvent, it may need to know which checkbox generated it. The diagram below shows two checkboxes sharing one listener, and the event carrying information that lets the listener tell them apart.
- Both checkboxes register the same listener object
evt.getSource()returns the object that generated the event, typed as Object, so it is cast toJCheckBoxevt.getActionCommand()returns the action command, which by default is the checkbox labelsource.isSelected()reads the state of whichever checkbox fired
Notice that the handler does not need to track the state itself. It asks the source checkbox for its current state. Because getSource() returns the object that generated the event, the cast to JCheckBox is needed before isSelected() can be called on it.
Mistakes Beginners Make with Checkbox Events
Common mistake Expecting a listener to run after setSelected() is called in code
What it looks likeA listener prints a message, and the program calls setSelected(true) on the box, but nothing is printed.
Why it failssetSelected()changes the state without generating anActionEvent, so no listener is notified.Do this insteadIf the code itself must react to a change, call the handling logic directly, or use doClick() when a simulated click that does generate an event is what you need.
Common mistake Confusing the variable name with the label
What it looks likeAssuming that a variable named showTime makes the box display the text showTime.
Why it failsThe variable name is only a name for the Java object. The label is the string argument passed to the constructor.
Do this insteadWrite the visible text in the constructor, for example new JCheckBox("Show Current Time").
Common mistake Calling isSelected() on the event instead of the source
What it looks likeWriting evt.isSelected() inside actionPerformed().Why it failsThe
ActionEventdoes not hold the checkbox state. The checkbox state is read from the component that generated the event.Do this insteadObtain the component with getSource(), cast it to JCheckBox, and then call isSelected() on it.
Common mistake Forgetting the cast after getSource()
Why it failsgetSource()returns type Object, so methods specific toJCheckBoxare not available until the value is cast.Do this insteadCast the returned value to JCheckBox before calling its methods.
Common mistake Assuming getActionCommand() returns the checkbox object rather than a string
Practice: Tracing a Checkbox Program
A program creates a checkbox with the label Show Date, registers a listener that prints the action command, and then calls setSelected(true) on the box. Before reading on, predict whether the listener prints anything. Then state what isSelected() would return immediately after the call.
Hints
- Think about which operations generate an
ActionEvent: a user click, or a call todoClick() setSelected()changes the boolean state; it does not generate an eventisSelected()reports the current boolean state at the moment it is called
Extend the shared-listener example so that the listener prints a different message depending on which checkbox fired. Use getActionCommand() for one approach and getSource() for the other, and explain which one you would choose when you need to call isSelected().
Hints
getActionCommand()returns a string, which by default is the checkbox labelgetSource()returns an Object that must be cast toJCheckBoxbeforeisSelected()can be called
Key Takeaways
- A
JCheckBoxhas two states, selected and unselected, represented by a boolean that is true when selected and false when unselected. - The label is passed to the
JCheckBoxconstructor;setSelected(boolean)sets the state andisSelected()reads it. - A user click generates an
ActionEventthat listeners registered withaddActionListener()receive;setSelected()generates no event, whiledoClick()simulates a click and does generate one. - Inside a handler,
getSource()returns the generating object, which needs a cast before its methods are called, andgetActionCommand()returns the action command, which by default is the checkbox label.