JCheckbox - ActionListener和ItemListener是什么?

65

在 JCheckBox 中,ActionListener 和 ItemListener 都用于触发事件。

那么它们之间有什么区别?在什么情况下更倾向于使用其中的一个?

5个回答

71

ItemListenerActionListenerJCheckBox中具有相同的行为。但是,主要区别在于,可以通过在复选框上调用setSelected(true) 来触发ItemListener。 作为编码实践,请勿同时注册ItemListenerActionListener,以避免不一致性。


我似乎发现了另一个差异,其中一个用户报告说当他们单击复选框时,ActionListener 没有被触发,但是当我将代码切换到ItemListener时,事件会触发。因此,actionPerformed是否触发可能取决于L&F或其他因素。 - Hakanai
"通过在复选框上调用setSelected(true),可以触发ItemListener。这非常有帮助!这个信息是在哪里记录的?还是您自己发现的?" - kevinarpe

29

两者的区别在于,当用户单击鼠标、按空格键或助记键更改JCheckBox的状态时,ActionEvent被触发。它并不真正监听JCheckBox是否被选中或取消选中的变化事件。

例如,如果将JCheckBox c1添加到一个ButtonGroup中,则更改ButtonGroup中其他JCheckBoxes的状态不会在其他JCheckBox上触发ActionEvent,而是会触发一个ItemEvent

最后说明:即使用户通过选择另一个JCheckBox(处于ButtonGroup中)来取消选中一个复选框,也会触发ItemEvent,但是不会生成ActionEvent。相反,ActionEvent仅侦听是否对注册了ActionListenerJCheckBox执行了操作。它不知道ButtonGroup和所有其他选择/取消选择相关的内容。


24

供参考,这里有一个展示差异的SSCCE

选择
执行操作
取消选择
执行操作

代码:

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 https://dev59.com/JGkw5IYBdhLWcg3wdKQv */
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();
            }
        });
    }
}

4

我在JButton上使用addActionListener,而对于JToggleButton,则更方便使用addItemListener。同时,在后一种情况下,当JToggleButton被选中/取消选中时,我使用if(event.getStateChange()==ItemEvent.SELECTED)添加事件。


1
对于 JCheckbox,无论是 ActionListener 还是 ItemListener 都不会在检查 isChecked 给出目标状态的阶段触发。event.getStateChange()==ItemEvent.SELECTED 是唯一有效的方法。 - Alexander Torstling

1
我已经进行了测试,并查看了此帖子上的所有答案,我认为它们并没有很好地回答这个问题。我自己进行了实验以得到一个好的答案(代码如下)。当单选按钮或复选框或任何其他类型的Swing项目更改状态时,您可以使用ActionListener和ItemListener 100%的时间触发任一事件,因为它是Object类型。我能够发现这两个侦听器之间唯一的区别是返回的侦听器事件对象类型不同。并且使用ItemListener比ActionListener更好地获得复选框的事件类型。
ActionEvent和ItemEvent的返回类型将具有不同的存储方法,可在事件类型被触发时使用。在下面的代码中,注释显示了每个类返回的事件类型的.get方法之间的差异。
以下代码设置了一个简单的JPanel,其中包含JRadioButtons、JCheckBoxes和一个基于按钮配置更改的JLabel显示。我使用ActionListener和ItemListener为所有RadioButtons和CheckBoxes设置。然后,我编写了下面的Listener类,其中ActionListener完全注释,因为我首先在这个实验中进行了测试。您会注意到,如果将此面板添加到框架并显示,所有单选按钮和复选框始终触发,无论监听器类型如何,只需在其中一个中注释掉方法,尝试另一个,反之亦然。
实现方法中的返回类型是两者之间的主要区别。两个监听器都以相同的方式触发事件。在上面的注释中更好地解释了应该使用ItemListener而不是ActionListener的原因,这是由于返回的事件类型。
package EventHandledClasses;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class RadioButtonsAndCheckBoxesTest extends JPanel{
JLabel display;
String funny, serious, political;
JCheckBox bold,italic;
JRadioButton funnyQuote, seriousQuote, politicalQuote;
ButtonGroup quotes;

    public RadioButtonsAndCheckBoxesTest(){
        funny = "You are not ugly, you were just born... different";
        serious = "Recommend powdered soap in prison!";
        political = "Trump can eat a little Bernie, but will choke on his     Birdie";

        display = new JLabel(funny);
        Font defaultFont = new Font("Ariel",Font.PLAIN,20);
        display.setFont(defaultFont);

        bold = new JCheckBox("Bold",false);
        bold.setOpaque(false);
        italic = new JCheckBox("Italic",false);
        italic.setOpaque(false);

        //Color itemBackground =

        funnyQuote = new JRadioButton("Funny",true);
        funnyQuote.setOpaque(false);
        seriousQuote = new JRadioButton("Serious");
        seriousQuote.setOpaque(false);
        politicalQuote = new JRadioButton("Political");
        politicalQuote.setOpaque(false);

        quotes = new ButtonGroup();
        quotes.add(funnyQuote);
        quotes.add(seriousQuote);
        quotes.add(politicalQuote);

        JPanel primary = new JPanel();
        primary.setPreferredSize(new Dimension(550, 100));

        Dimension standard = new Dimension(500, 30);

        JPanel radioButtonsPanel = new JPanel();
        radioButtonsPanel.setPreferredSize(standard);
        radioButtonsPanel.setBackground(Color.green);
        radioButtonsPanel.add(funnyQuote);
        radioButtonsPanel.add(seriousQuote);
        radioButtonsPanel.add(politicalQuote);

        JPanel checkBoxPanel = new JPanel();
        checkBoxPanel.setPreferredSize(standard);
        checkBoxPanel.setBackground(Color.green);
        checkBoxPanel.add(bold);
        checkBoxPanel.add(italic);

        primary.add(display);
        primary.add(radioButtonsPanel);
        primary.add(checkBoxPanel);

        //Add Action Listener To test Radio Buttons
        funnyQuote.addActionListener(new ActionListen());
        seriousQuote.addActionListener(new ActionListen());
        politicalQuote.addActionListener(new ActionListen());

        //Add Item Listener to test Radio Buttons
        funnyQuote.addItemListener(new ItemListen());
        seriousQuote.addItemListener(new ItemListen());
        politicalQuote.addItemListener(new ItemListen());

        //Add Action Listener to test Check Boxes
        bold.addActionListener(new ActionListen());
        italic.addActionListener(new ActionListen());

        //Add Item Listener to test Check Boxes
        bold.addItemListener(new ItemListen());
        italic.addItemListener(new ItemListen());

        //adds primary JPanel to this JPanel Object
        add(primary);   
    }

    private class ActionListen implements ActionListener{

        public void actionPerformed(ActionEvent e) {

         /*
         Different Get Methods from  ItemEvent 
         e.getWhen()
         e.getModifiers()
         e.getActionCommand()*/

            /*int font=Font.PLAIN;
            if(bold.isSelected()){
                font += Font.BOLD;
            }
            if(italic.isSelected()){
                font += Font.ITALIC;
            }
            display.setFont(new Font("Ariel",font,20));

            if(funnyQuote.isSelected()){
                display.setText(funny);
            }
            if(seriousQuote.isSelected()){
                display.setText(serious);
            }
            if(politicalQuote.isSelected()){
                display.setText(political);
            }*/
        }
    }
    private class ItemListen implements ItemListener {

        public void itemStateChanged(ItemEvent arg0) {

            /*
            Different Get Methods from ActionEvent
            arg0.getItemSelectable()
            arg0.getStateChange()
            arg0.getItem()*/


            int font=Font.PLAIN;
            if(bold.isSelected()){
                font += Font.BOLD;
            }
            if(italic.isSelected()){
                font += Font.ITALIC;
            }
            display.setFont(new Font("Ariel",font,20));

            if(funnyQuote.isSelected()){
                display.setText(funny);
            }
            if(seriousQuote.isSelected()){
                display.setText(serious);
            }
            if(politicalQuote.isSelected()){
                display.setText(political);
            }

        }

    }
}

所以,你说两种都可以,但你更喜欢ItemState / ItemListener。 - Sam Ginrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接