JCheckbox - ActionListener and ItemListener?
Both ItemListener
as well as ActionListener
, in case of JCheckBox
have the same behaviour.
However, major difference is ItemListener
can be triggered by calling the setSelected(true)
on the checkbox.
As a coding practice do not register both ItemListener
as well as ActionListener
with the JCheckBox
, in order to avoid inconsistency.
The difference is that ActionEvent
is fired when the action is performed on the JCheckBox
that is its state is changed either by clicking on it with the mouse or with a space bar or a mnemonic. It does not really listen to change events whether the JCheckBox
is selected or deselected.
For instance, if JCheckBox c1
(say) is added to a ButtonGroup
. Changing the state of other JCheckBoxes
in the ButtonGroup
will not fire an ActionEvent
on other JCheckBox
, instead an ItemEvent
is fired.
Final words: An ItemEvent
is fired even when the user deselects a check box by selecting another JCheckBox
(when in a ButtonGroup
), however ActionEvent
is not generated like that instead ActionEvent
only listens whether an action is performed on the JCheckBox
(to which the ActionListener
is registered only) or not. It does not know about ButtonGroup
and all other selection/deselection stuff.
For reference, here's an sscce that illustrates the difference. Console:
SELECTED ACTION_PERFORMED DESELECTED ACTION_PERFORMED
Code:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** @see http://stackoverflow.com/q/9882845/230513 */
public class Listeners {
private void display() {
JFrame f = new JFrame("Listeners");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JCheckBox b = new JCheckBox("JCheckBox");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getID() == ActionEvent.ACTION_PERFORMED
? "ACTION_PERFORMED" : e.getID());
}
});
b.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
System.out.println(e.getStateChange() == ItemEvent.SELECTED
? "SELECTED" : "DESELECTED");
}
});
JPanel p = new JPanel();
p.add(b);
f.add(p);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Listeners().display();
}
});
}
}
I use addActionListener
for JButtons while addItemListener
is more convenient for a JToggleButton
. Together with if(event.getStateChange()==ItemEvent.SELECTED)
, in the latter case, I add Events for whenever the JToggleButton is checked/unchecked.