English 中文(简体)
是否有办法防止行动聆听者在被点选时开枪?
原标题:Is there a way to prevent action listeners from firing when setSelectedItem() is called?

I have a program with multiple comboboxes, each with their own action listener. Selecting an item from any of the comboboxes will change the items in one or more of the other comboboxes. The problem I m running into is that calling setSelectedItem() for one combobox will fire the action listener for another combobox, which in turn fires the action listeners of the other ones, etc etc.

是否有办法避免这种情况,要么只允许行动听众从用户投入中发射,要么发现行动不是从用户投入发射? 说不使用定型号,这不是一种选择,因为我希望该方案能够为每个箱子确定目前选定的项目。 事先得到任何帮助。

最佳回答

例如

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);
    }
}
问题回答

我认为这是可能的。 如果你在 com子上设定行动清单,那么actionPerform()将总是在偶然发生任何事件时发出。 它没有检查活动是由用户还是通过方案产生的。

但是,你只能把mouselistner放在你 com的箱子上,这样,只有当你点击 you子时,才会采取具体的行动。

Also another way is to set flag for this to check that whether the event is generated by user or through program.

但是,我预示着在 com木箱上设置 mo化器的第一个方法。

一种办法是增加PopupMenuListener,而不是行动听众。 其popupMenuWillBecomeInvisible 这种方法将在用户手工选择一个项目后发射,但不得在<条码>后发射。

I ve found one limitation to this method: if the user keeps the dropdown closed and selects an item by typing its first letter, the popup listener won t fire. In the example below, I worked around this by preventing the user from selecting items by typing alphabetical characters.

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class ComboBoxExample extends JFrame {

    public static void main(String[] args) {

        JFrame frame = new JFrame("JComboBox Example");

        // Create combo box
        JComboBox homeTypeComboBox = new JComboBox(new String[]{"House", "Condo", "Apartment"});
        
        // add the popup listener
        homeTypeComboBox.addPopupMenuListener(new HomeTypeChangeListener());

        // prevent user from selecting an item by typing its first letter
        homeTypeComboBox.setKeySelectionManager((key, model) -> { return -1; });

        JPanel panel = new JPanel();
        panel.add(homeTypeComboBox);

        frame.add(panel);
        frame.setSize(300, 150);
        frame.show();

        // These will not generate print statements
        homeTypeComboBox.setSelectedItem("House");
        homeTypeComboBox.setSelectedItem("Condo");
        homeTypeComboBox.setSelectedItem("Apartment");
    }

    private static class HomeTypeChangeListener implements PopupMenuListener {
        
        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}

        public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            // triggered when user makes a dropdown selection
            System.out.println("User changed the dropdown selection. This will not be triggered for programmatic" 
                + " calls to JComboBox::setSelectedItem, JComboBox::setSelectedIndex, or JComboBox::addItem.");
        }

        public void popupMenuCanceled(PopupMenuEvent e) {}
    }

}





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签