将侦听器添加到 JPanel

Add listener to JPanel

我有一个扩展 JPanel 的自定义 class CustomField。由于我经常需要重复使用相同的模式,因此我的自定义 class 由 2 个 JLabel 和 2 个 JComboBox 组成。 这很简单;第一个 JComboBox 有 ON/OFF 个选项,第二个 JComboBox 只有在第一个设置为 "ON" 时才可见。我可以管理这部分。 然而,我不知道由谁来设计它的部分是 CustomField 实例在另一个 class 中,这是主要的 JFrame 并且在这个 JFrame 中,只有当 CustomField 中的 JComboBox class 设置为 "ON"。我考虑过使用 MouseAdapter,但我不知道这是个好习惯。

这是我的自定义字段 class:

public class CustomField extends JPanel {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    JLabel text, portText;
    JComboBox<String> testCB, option;

    public CustomField(String text, String opt, String tst) {
        this.text = new JLabel(text);

        String[] onOffOpt= {"OFF", "ON"};
        this.option = new JComboBox<String>(onOffOpt);
        this.option.setSelectedItem(opt);
        this.option.addItemListener(new ItemListener(){
            @Override
            public void itemStateChanged(ItemEvent ie) {
                portText.setVisible(option.getSelectedIndex() == 1);
                testCB.setVisible(option.getSelectedIndex() == 1);
            }
        });

        this.portText = new JLabel("Test:");

        String[] testChoices = {"Test", "Test2"};
        this.testCB = new JComboBox<String>(testChoices);
        this.testCB.setSelectedItem(tst);

        this.setLayout(new FlowLayout());
        add(this.text);
        add(this.option);
        add(this.portText);
        add(this.testCB);
    }
}

这是主要的 JFrame:

public class Main {
    CustomField cf = new CustomField("test", "ON, "Test2");
    public static void main(String s[]) {

        JFrame frame = new JFrame("Application");

        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());


        panel.add(cf);

        JLabel labelTest = new JLabel("Label that should be visible or not");
        panel.add(labelTest);

        frame.add(panel);
        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

基本上,我希望 labelTest 根据 CustomField 设置进行明显更改。按照制作方式,我无法将 labelTest 放入 CustomField class.

有没有一种干净的方法来做我想做的事?我应该重新设计实际的东西并将所有字段放在同一个 class 中吗?

谢谢!

首先,您想使用 CustomField 中的方法公开组合框的状态:

public boolean isOn() {
    return testCB.getSelectedIndex() == 1;
}

您可以通过查看各种 Swing 组件文档中的方法签名来了解如何完成状态侦听,这些组件使用标准的 JavaBean 侦听器模式:您需要添加三个 public 方法,以及一个受保护的方法:

public void addChangeListener(ChangeListener listener) {
    listenerList.add(ChangeListener.class, listener);
}

public void removeChangeListener(ChangeListener listener) {
    listenerList.remove(ChangeListener.class, listener);
}

public ChangeListener[] getChangeListeners() {
    return listenerList.getListeners(ChangeListener.class);
}

protected void fireChangeListeners() {
    ChangeEvent event = new ChangeEvent(this);
    for (ChangeListener listener : getChangeListeners()) {
        listener.stateChanged(event);
    }
}

(listenerList字段继承自JComponent。)

现在,只要检测到用户更改了 On/Off 组合框的值,您就可以简单地添加对 fireChangeListeners(); 的调用——也就是说,您需要在您的ItemListener.

正如您可能猜到的那样,您的 Main class 现在可以调用 cf.addChangeListener,并且在该侦听器内部根据 cf.isOn() 返回的值调整标签的可见性。

您可以通过阅读 these 学到更多东西。