【问题标题】:JComboBox Action listenerJComboBox 动作监听器
【发布时间】:2011-09-26 05:01:53
【问题描述】:

我遇到了这个问题。 我有多个 JComboBox(共 5 个)。

我为每个组合框添加了一个 ActionListener,但所有组合框都使用相同的 ActionListener,称为:

ComboBoxActionPerformed(java.awt.event.ActionEvent e)

当执行该操作时,我会查看事件 (e) 并执行以下操作:

JComboBox c = ((JComboBox)e.getSource());
//DO WORK relating to c as thats the combobox that triggered.

但问题是,当我在任何组合框中更改某些内容时,Action 总是由我附加 actionlistner 的最后一个组合框触发。

有人知道吗?

然后我切换到 ItemListner。 这就是我正在做的事情

class MyActionListner implements ItemListener 
{
    //STUFF
        @Override
        public void itemStateChanged(ItemEvent evt) 
        {
            //DO STUFF
    }
}

public JComboBox createCombo()
{
    JComboBox box = new JComboBox();
        box.setModel(new javax.swing.DefaultComboBoxModel(new String[] 
                { "val1", "val2","val3" }));
        RulesActionListner actionL = new RulesActionListner();
        box.addItemListener(actionL);
return box;
}

并且 createCombo 被多次调用 但无论在我的 ItemStateChanged 方法中更改了哪个组合框项 来自上一个创建的组合框

createCombo 在运行时被调用,所以我有可变数量的组合框。

【问题讨论】:

  • 你所说的“问题是当我改变某些东西时”是什么意思。是 GUI 更改(选择)还是程序化更改(通过模型)。
  • 为了减少监听所有事件添加到你的“itemStateChanged()”这个代码行“if (e.getStateChange() == ItemEvent.SELECTED) {}”
  • 似乎没有人找到,请发布整个代码。我希望能够编译和测试。

标签: java swing jcombobox actionlistener


【解决方案1】:

添加单独的操作侦听器,而不是让一个操作侦听器在每次调用的 if 语句中运行。该代码部分的逻辑很可能存在导致选择最后一个组合框的错误。 (也许应该是 else ifelse 语句等)。

将其分离出来会更加面向对象,并且从长远来看会更加灵活。

【讨论】:

  • if (e.getSource() == myCombo1) {... +1
【解决方案2】:

@user650608 你的问题对我来说不是很清楚,你的意思是 - 走这条路,还是我错了?,

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", "Size"};
        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.CENTER);
        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);
        String[] subItems4 = {"Select Size", "Big", "Middle", "Small"};
        subItems.put(items[4], subItems4);
    }

    @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);
    }
}

【讨论】:

  • 问题是我的组合框是动态创建的。所以我没有固定数量的组合框。
  • @user650608 这是...的答案,我再次仔细阅读了您的问题,我的问题也是
【解决方案3】:

您是否尝试使用 ItemListener 代替?

The doc 表示每次编辑组合框时都会触发一个 ActionEvent。

问候, 斯蒂芬

【讨论】:

  • @little bunny foo foo 这不是真的,那不正确 JComboBox 的监听器(我的观点),@Snicolas +1
  • @mKorbel,你在说什么?
  • @little bunny foo foo ,没有什么复杂的,如果 Item 改变并且动作有方向改变 JComboBox 本身,那么 ActionListener 是正确的决定,因为从 JComboBox 输出到 GUI 是更好的 ItemListener :-),我知道sn-Oracle 页面上的官方教程 ...
  • @mKorbel,好吗?我只是说注册ItemListener 的建议不会在这种特殊情况下产生影响。我不确定你在向谁讲道......
  • @little bunny foo foo '我不确定你在向谁说教......' 尊敬的,我并没有反对你的人......
猜你喜欢
  • 2021-07-02
  • 2011-09-03
  • 2010-09-08
  • 1970-01-01
  • 2013-12-24
  • 2013-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多