编写Swing组件:如何添加添加ActionListeners的能力?

我想创build一个(简单的,希望)自定义的Swing组件,通过组合现有的几个组件。 就我而言,它是一个由JLabel组成的开关开关,以及两个用于On和Off的JButton。 我通过扩展JPanel来开始OnOffSwitch。 构造函数添加子组件,并将其自身设置为button的ActionListener。 该类有一个isOn()方法来查询组件的当前状态。

我现在想添加将ActionListeners添加到OnOffSwitch类的function。 我预计这个function可以通过扩展一个像JPanel这样的Swing组件来实现,但是JPanel没有这个function。 通过源代码的外观,每个具有此function的Swing组件都会自行重新实现它:向列表添加侦听器,触发ActionEvents等。

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

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

我宁愿组合而不是inheritance。 有一个拥有Swing数据成员的UI类,并为它提供添加和删除监听器的方法。 你可以改变这种行为,而不必重写UI类。 它不过是一个容器。

public class MyUI { private Button b = new Button(); public void addButtonListener(ActionListener listener) { this.b.addActionListener(listener); } } 

我将使用JToggelButton ,如下所示,或委托给包含的button,@duffymobuild议。 如果你确实需要一个自定义的OnOffSwitchEvent ,那么标准接线在EventListenerList概述,其实例包含在每个JComponent

附录:下面是一个委托给包含两个button的ButtonGroup的例子。 标签用一个符号来装饰,但任何Icon实现都更加灵活。

BttonGroupTest iamge

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

通过源代码的外观,每个具有这个[ActionListener]function的Swing组件都自己重新实现它:向列表中添加监听器,触发ActionEvents等等。

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

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