Java 编写Swing组件:如何添加添加ActionListener的功能?

Java 编写Swing组件:如何添加添加ActionListener的功能?,java,swing,custom-controls,actionlistener,Java,Swing,Custom Controls,Actionlistener,我想通过组合几个现有组件来创建一个(简单,希望如此)定制Swing组件。在我的例子中,它是一个on-off开关,由一个JLabel和两个用于on和off的JButton组成。我通过扩展JPanel开始OnOffSwitch。构造函数添加子组件,并将自己设置为按钮的ActionListener。该类有一个isOn()方法用于查询组件的当前状态 现在我想添加将ActionListeners添加到OnOffSwitch类的功能。我希望通过扩展像JPanel这样的Swing组件,这个功能将免费提供,但J

我想通过组合几个现有组件来创建一个(简单,希望如此)定制Swing组件。在我的例子中,它是一个on-off开关,由一个JLabel和两个用于on和off的JButton组成。我通过扩展JPanel开始OnOffSwitch。构造函数添加子组件,并将自己设置为按钮的ActionListener。该类有一个isOn()方法用于查询组件的当前状态

现在我想添加将ActionListeners添加到OnOffSwitch类的功能。我希望通过扩展像JPanel这样的Swing组件,这个功能将免费提供,但JPanel没有这个功能。从源代码的外观来看,每个具有此功能的Swing组件都会重新实现它自己:向列表中添加侦听器、触发ActionEvents等等

实现我想要的东西的正确方法是什么?我可以从各种Swing组件复制/粘贴代码(或者重新编写其要点),或者实现自己的OnOffSwitchListener接口。为了保持一致,我的所有组件似乎都应该使用ActionListeners

从源代码的外观来看,每个具有[ActionListener]功能的Swing组件都会重新实现它自己:向列表中添加侦听器、触发ActionEvents等等

是的。这就是编写自定义Swing组件时必须执行的操作


正如您所说,您可以从现有的Swing组件复制
ActionListener
代码,

我个人认为您不需要定制Swing组件。您的UI类不需要扩展任何Swing类;您不太可能提供太多自定义行为。(我可能会承认一个JPanel可以组成其他人。)

我更喜欢构图而不是继承。拥有一个包含Swing数据成员的UI类,并根据需要为其提供添加和删除侦听器的方法。您可以通过这种方式更改行为,而无需重写UI类。它只不过是一个容器而已

public class MyUI
{
    private Button b = new Button();

    public void addButtonListener(ActionListener listener) { this.b.addActionListener(listener); }
}

我会使用
JToggelButton
,如图所示,或者像@duffymo所建议的那样,委托给包含的按钮。如果您确实需要自定义的
OnOffSwitchEvent
,中概述了标准接线,每个
JComponent
中都包含了标准接线的实例

附录:下面是一个委派给包含两个按钮的
按钮组的示例。标签用符号装饰,但
图标的任何实现都更加灵活

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JToggleButton;

/** @see https://stackoverflow.com/questions/6035834 */
public class ButtonGroupTest extends JComponent {

    private static final String ON = "On";
    private static final String OFF = "Off";
    private final JToggleButton bOn = new JToggleButton(ON);
    private final JToggleButton bOff = new JToggleButton(OFF);
    private final JLabel label = new JLabel(" \u2301 ");
    private final ButtonHandler handler = new ButtonHandler();

    public ButtonGroupTest() {
        this.setLayout(new FlowLayout());
        label.setOpaque(true);
        label.setBackground(Color.red);
        label.setFont(label.getFont().deriveFont(36f));
        ButtonGroup bg = new ButtonGroup();
        this.add(bOn);
        bg.add(bOn);
        bOn.setSelected(true);
        bOn.addActionListener(handler);
        this.add(label);
        this.add(bOff);
        bg.add(bOff);
        bOff.addActionListener(handler);
    }

    public void addActionListener(ActionListener listener) {
        bOn.addActionListener(listener);
        bOff.addActionListener(listener);
    }

    private class ButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String cmd = e.getActionCommand();
            if (ON.equals(cmd)) {
                label.setBackground(Color.red);
            } else {
                label.setBackground(Color.black);
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("ButtonGroupTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ButtonGroupTest().display();
            }
        });
    }
}


+1我同意使用现有组件进行合成;对不起,我刚才误读了。