组合 Swing 组件:如何添加添加 ActionListener 的功能?
Posted
技术标签:
【中文标题】组合 Swing 组件:如何添加添加 ActionListener 的功能?【英文标题】:Composing Swing Components: How do I add the ability to add ActionListeners? 【发布时间】:2011-08-27 12:12:41 【问题描述】:我想通过组合几个现有组件来创建一个(希望是简单的)自定义 Swing 组件。在我的例子中,它是一个开关,由一个 JLabel 和两个用于打开和关闭的 JButton 组成。我从扩展 JPanel 开始 OnOffSwitch。构造函数添加子组件,并将自己设置为按钮的 ActionListener。该类有一个 isOn() 方法用于查询组件的当前状态。
我现在想添加将 ActionListeners 添加到 OnOffSwitch 类的功能。我希望通过扩展 JPanel 之类的 Swing 组件来免费提供此功能,但 JPanel 没有此功能。从源代码来看,每个具有此功能的 Swing 组件都会重新实现它自己:将侦听器添加到列表、触发 ActionEvents 等。
实现我想要的正确方法是什么?我可以从各种 Swing 组件复制/粘贴该代码(或重写它的要点),或者我可以实现我自己的 OnOffSwitchListener 接口。为了保持一致,我的所有组件似乎都应该使用 ActionListeners。
【问题讨论】:
【参考方案1】:从源代码来看,每个确实具有此 [ActionListener] 功能的 Swing 组件都会重新实现它自己:将侦听器添加到列表中,触发 ActionEvents 等。
是的。这就是您在编写自定义 Swing 组件时必须做的事情。
如您所说,您可以从现有的 Swing 组件中复制 ActionListener
代码,
【讨论】:
【参考方案2】:我个人认为您不需要自定义 Swing 组件。您的 UI 类无需扩展任何 Swing 类;您不太可能提供太多自定义行为。 (我可能会承认 JPanel 可以组合其他人。)
我更喜欢组合而不是继承。拥有一个具有 Swing 数据成员的 UI 类,并为其提供根据需要添加和删除侦听器的方法。您可以通过这种方式更改行为,而无需重写 UI 类。它只不过是一个容器。
public class MyUI
private Button b = new Button();
public void addButtonListener(ActionListener listener) this.b.addActionListener(listener);
【讨论】:
+1 我同意使用现有组件进行组合;抱歉我之前的误读。【参考方案3】:我会使用JToggelButton
,如here 所示,或委托给包含的按钮,如@duffymo 建议的那样。如果您真的需要自定义OnOffSwitchEvent
,标准接线在EventListenerList
中列出,每个JComponent
中都包含一个实例。
附录:这是一个委托给包含两个按钮的 ButtonGroup
的示例。标签用符号装饰,但Icon
的任何实现都更加灵活。
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://***.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();
);
【讨论】:
以上是关于组合 Swing 组件:如何添加添加 ActionListener 的功能?的主要内容,如果未能解决你的问题,请参考以下文章