JPanel Action Listener
问题描述:
我有一堆不同的复选框和文本字段的JPanel,我有一个禁用的按钮,需要在特定配置设置时启用。 我需要的是在整个JPanel寻找事件时的一个监听器,只要有任何改变。 我相信我需要一个动作侦听器,但我无法找到任何与JpanelJPanel Action Listener
JPanel Window = new JPanel();
Window.addActionListener(new ActionListener(){
//Check if configurations is good
}
弥合的动作监听我想我可以在面板中复制和粘贴我的代码一堆次到每一个听众,但这对我来说似乎是不好的编码习惯。
答
首先作为@Sage在他的comment中提到a JPanel是一个容器,而不是执行操作的组件。所以你不能附加ActionListener到JPanel
。
我想我可以复制粘贴一段代码到面板中的每个 监听器中,但这对我来说似乎是不好的编码习惯。
你说的完全正确,根本不是一个好习惯(见DRY principle)。取而代之的是你可以定义一个ActionListener
并将其连接到您的JCheckBox
ES这样的:
final JCheckBox check1 = new JCheckBox("Check1");
final JCheckBox check2 = new JCheckBox("Check2");
final JCheckBox check3 = new JCheckBox("Check3");
final JButton buttonToBeEnabled = new JButton("Submit");
buttonToBeEnabled.setEnabled(false);
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean enable = check1.isSelected() && check3.isSelected();
buttonToBeEnabled.setEnabled(enable);
}
};
check1.addActionListener(actionListener);
check2.addActionListener(actionListener);
check3.addActionListener(actionListener);
这意味着:如果check1
和check3
都选中,则该按钮必须启用,否则必须将其禁用。当然,只有您知道应该选择哪些复选框组合才能设置启用按钮。
答
有人建议可以从每个您使用的组件的派生类,并添加冒泡容器树,寻找实现这样的定制界面的第一个容器一个ActionListener:
public interface MyCommandProcessor {
void execute(String actionCommand);
}
public class MyButton extends JButton {
public MyButton(string actionCommand) {
setActionCommand(actionCommand);
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
Container traverser = MyButton.this;
while (traverser != null && !(traverser instanceof MyCommandProcessor))
traverser = traverser.getParent();
if (traverser != null)
((CommandListener)traverser).execute(ae.getActionCommand());
}
});
}
}
public class MyApp extends JFrame implements MyCommandListener {
public MyApp() {
JPanel panel = new Panel();
panel.add(new MyButton("MyButton got pressed"));
}
public void execute(String actionCommand) {
System.out.println(actionCommand);
}
}
答
您需要创建自定义组件侦听器。看看这里:
Creating Custom Listeners In Java
http://www.javaworld.com/article/2077333/core-java/mr-happy-object-teaches-custom-events.html
我这样做是抛出标准的ActionListener 例
public class MyPanel extends JPanel {
private final JComboBox<String> combo1;
private final JButton btn2;
.......
//catch the actions of inside components
btn2.addActionListener(new MyPanelComponentsActionListener());
........
//assign actionlistener to panel class
public void addActionListener(ActionListener l) {
listenerList.add(ActionListener.class, l);
}
public void removeActionListener(ActionListener l) {
listenerList.remove(ActionListener.class, l);
}
//handle registered listeners from components used MyPanel class
protected void fireActionPerformed(ActionEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (e == null) {
String actionCommand = event.getActionCommand();
if(actionCommand == null) {
actionCommand = "FontChanged";
}
e = new ActionEvent(FontChooserPanel.this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
event.getWhen(),
event.getModifiers());
}
// here registered listener executing
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
//!!! here your event generator
class MyPanelComponentsActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//do something usefull
//.....
fireActionPerformed(e);
}
}
....
}
具体到你说话的配置。 'JPanel'不是一个容器,而是一个能够执行操作的'Controller'组件。点击一个按钮是一个动作,就像你开启和关闭它一样。点击一个复选框是一个动作,就像您使用刻度线选择您感兴趣的数据一样。 – Sage