【问题标题】:Add listener to JPanel将侦听器添加到 JPanel
【发布时间】:2016-05-20 19:26:59
【问题描述】:

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

这是我的 CustomField 类:

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 类中。

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

谢谢!

【问题讨论】:

  • 实现ChaneListenerActionListener 可以通知相关方您的自定义组件的状态已更改
  • "第一个 JComboBox 有 ON/OFF 选项" 为什么不使用 JToggleButton?

标签: java jpanel listener


【解决方案1】:

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

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

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

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 类现在可以调用 cf.addChangeListener,并在该侦听器内部根据 cf.isOn() 返回的值调整标签的可见性。

您可以通过阅读these了解更多信息。

【讨论】:

    猜你喜欢
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 2011-09-28
    • 2023-03-27
    • 2022-10-20
    • 2012-06-02
    • 2016-08-21
    相关资源
    最近更新 更多