【问题标题】:Is there a way to prevent action listeners from firing when setSelectedItem() is called?有没有办法在调用 setSelectedItem() 时阻止动作侦听器触发?
【发布时间】:2012-05-11 13:39:15
【问题描述】:

我有一个包含多个组合框的程序,每个组合框都有自己的动作监听器。从任何组合框中选择一个项目将更改一个或多个其他组合框中的项目。我遇到的问题是,为一个组合框调用 setSelectedItem() 会触发另一个组合框的动作侦听器,而后者又会触发其他组合框的动作侦听器,等等。

有没有办法避免这种情况,要么只允许从用户输入触发动作侦听器,要么检测到动作不是从用户输入触发的?说不使用 setSelectedItem() 不是一个选项,因为我希望程序能够为每个组合框设置当前选定的项目。提前感谢您的帮助。

【问题讨论】:

    标签: java swing jcombobox actionlistener comboboxmodel


    【解决方案1】:

    我认为这是不可能的。如果您在组合框上设置了 actionlistener,那么只要组合框上生成任何事件,actionPerformed() 就会始终调用。它不检查事件是由用户产生还是通过程序产生。

    但是你可以在你的组合框上设置mouselistner,所以只有当你点击你的组合框时,才会执行指定的操作。

    另一种方法是为此设置标志以检查事件是由用户生成还是通过程序生成。

    但我更喜欢在组合框上设置 mouselistener 的第一种技术。

    【讨论】:

    • 很高兴你提到了这一点。我为类似的情况设置了一个标志。 is_editing = false;(只是为了说明)
    • 我有类似的问题,但不确定该标志将如何帮助我。当用户更改标志时,如何将标志更改回true?例如当程序更改项目时,我可以轻松地将标志设置为 false...但是 true 呢?
    • 好吧,没关系,呃,我明白了。设置为 false,更改组合框,然后设置回 true。在actionPerformed() 中,我只检查标志。
    【解决方案2】:

    例如

    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    
    public class ComboBoxTwo extends JFrame implements ActionListener, ItemListener {
    
        private static final long serialVersionUID = 1L;
        private JComboBox mainComboBox;
        private JComboBox subComboBox;
        private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>();
    
        public ComboBoxTwo() {
            String[] items = {"Select Item", "Color", "Shape", "Fruit"};
            mainComboBox = new JComboBox(items);
            mainComboBox.addActionListener(this);
            mainComboBox.addItemListener(this);
            //prevent action events from being fired when the up/down arrow keys are used
            //mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
            getContentPane().add(mainComboBox, BorderLayout.WEST);
            subComboBox = new JComboBox();//  Create sub combo box with multiple models
            subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
            subComboBox.addItemListener(this);
            getContentPane().add(subComboBox, BorderLayout.EAST);
            String[] subItems1 = {"Select Color", "Red", "Blue", "Green"};
            subItems.put(items[1], subItems1);
            String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"};
            subItems.put(items[2], subItems2);
            String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"};
            subItems.put(items[3], subItems3);
    //      mainComboBox.setSelectedIndex(1);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            String item = (String) mainComboBox.getSelectedItem();
            Object o = subItems.get(item);
            if (o == null) {
                subComboBox.setModel(new DefaultComboBoxModel());
            } else {
                subComboBox.setModel(new DefaultComboBoxModel((String[]) o));
            }
        }
    
        @Override
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                if (e.getSource() == mainComboBox) {
                    if (mainComboBox.getSelectedIndex() != 0) {
                        FirstDialog firstDialog = new FirstDialog(ComboBoxTwo.this,
                                mainComboBox.getSelectedItem().toString(), "Please wait,  Searching for ..... ");
                    }
                } 
            }
        }
    
        private class FirstDialog extends JDialog {
    
            private static final long serialVersionUID = 1L;
    
            FirstDialog(final Frame parent, String winTitle, String msgString) {
                super(parent, winTitle);
                setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
                JLabel myLabel = new JLabel(msgString);
                JButton bNext = new JButton("Stop Processes");
                add(myLabel, BorderLayout.CENTER);
                add(bNext, BorderLayout.SOUTH);
                bNext.addActionListener(new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        setVisible(false);
                    }
                });
                javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        setVisible(false);
                    }
                });
                t.setRepeats(false);
                t.start();
                setLocationRelativeTo(parent);
                setSize(new Dimension(400, 100));
                setVisible(true);
            }
        }
    
        public static void main(String[] args) {
            JFrame frame = new ComboBoxTwo();
            frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-10-13
      • 2015-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      相关资源
      最近更新 更多