[英]Can I add an ActionListener to a button in a jFrame and have the actionPerformed method in a different Class?
[英]Can addition of an ActionListener be short? Can I add arguments to the actionPerformed?
我有一个大表,每个单元格中都有一个按钮。 这些按钮非常相似,几乎相同。 如果我以这种方式向每个按钮添加一个动作侦听器:
tmp.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent evt) {
proposition = proposition + action;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updatePropositionPanel();
}
});
}
});
其实,每一个动作监听器与所有其他由的值不同action
。 proposition
和updatePropositionPanel
是该类的字段和方法。
首先,如果我不使用内部类,我认为我可以缩短它。 所以,我决定编写一个新的ActionListener类。 但是我意识到在这种情况下,“命题”对于这个类的实例是不可见的。
然后我决定将actionPerformed方法添加到当前类并执行: addActionListener(this)
。 但是我意识到我不知道如何为actionPerformed方法提供参数。
那么它是怎样工作的。 我可以以简短的方式添加动作侦听器吗?
添加:
我喜欢用构造函数编写内部类的想法,它可以使用一些参数和actioPerformed方法,它可以使用构造函数中给出的参数。 我开始这样做,然后意识到它与其他内部匿名类创建冲突(像上面给出的代码一样使用)。 所以,我想我会创建另一个类(不是内部类)。
您可以创建自己的类并将数据传递给构造函数。 例如
public class MyActionListener
{
private int proposition;
private MyOtherClass moc;
public MyActionListener(int proposition, MyOtherClass moc) {
this.proposition = proposition;
this.moc = moc;
}
public void actionPerformed(ActionEvent evt) {
proposition += moc.action;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
moc.updatePropositionPanel();
}
});
}
}
然后你可以正常添加它,将你喜欢的任何参数传递给构造函数:
tmp.addActionListener( new MyActionListener(proposition, this) );
编辑 :我已经改变了类来显示MyOuterClass的构造。
这里有一些代码勾勒出来。 希望这会得到你的1,这就是我实现它的方式。
public class MyOuterClass {
// member variables for MyOuterClass
public MyOuterClass() {
// ...constructor stuff here
}
// ...outer class stuff here - methods, etc.
// The code each place you want to add the listener, somewhere in MyOuterClass
tmp.addActionListener(new MyActionListener(poposition, action));
// below outer class stuff, although it can really be most places, I usually put
// it here - personal style preference. Swing's classes often put inner
// classes first
/**
* An inner class.
*/
private MyActionListener implements ActionListener {
/**
* Object used here as a filler, replace with appropriate
* class types
*/
private Object proposition;
private Object action;
private MyActionListener(Object proposition, Object action) {
this.proposition = proposition;
this.action = action;
}
public void actionPerformed(ActionEvent evt) {
proposition = proposition + action;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updatePropositionPanel();
}
}
/**
* Setters provided in case you need to change proposition and action. If not,
* feel free not to have them and to have final members
*/
private void setProposition(Object proposition) {
this.proposition = proposition;
}
private void setAction(Object action) {
this.action = action;
}
}
}
编辑 :要在编辑中按要求创建另一个类,请执行上述操作,但在另一个.java文件中创建非私有其他类并编写代码。
唯一不同的是action
的价值,您可以将代码放在方法中。 (另外@Override是不必要的, +=
在这里很有用。)
public void setup(
final AbstractButton button,
final int action
) {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
proposition += action;
EventQueue.invokeLater(new Runnable() {
public void run() {
updatePropositionPanel();
}
});
}
});
}
invokeLater
可能毫无意义,因为无论如何你将参加AWT事件调度线程(EDT)。
如果要添加许多通用操作,则可以使用没有与之关联的无意义事件对象的接口来简化它。
如果你想成为hackish,你可以在子类构造函数中添加监听器。
new ActionHandler(button) { public void action() {
proposition += action;
updatePropositionPanel();
}});
希望JDK7能够使这种事情的Java语法不那么冗长。 但是,Java总是有点冗长。
如果你使proposition
可变,则选项1有效(例如StringBuilder
而不是String
)。 如果您将其声明为final
则选项2有效。 这样它们在内部类中是可访问/可见的。
您可以创建一个单独的MyActionListener类,并使用构造函数传递两个值命题和操作。 它整理了源代码。
您可以创建自己的侦听器类来实现ActionListener。 该类可以包含与您正在讨论的参数对应的成员变量; 你可以使用构造函数设置它们。
添加侦听器的调用将看起来像这样:
tmp.addActionListener(new MyActionListenerSubClass(proposition, action));
为了这个例子,我假设你的命题和动作变量是字符串。 定义一个接口PropositionUpdater,一个接口PropositionPanelUpdater和一个协作者提议持有者:
public interface PropositionUpdater() {
public void updateProposition(PropositionHolder holder, String action);
}
public interface PropositionHolder() {
public String getProposition();
public void setProposition(String proposition);
}
public interface PropositionPanelUpdater() {
public void updatePropositionPanel();
}
命题更新程序的默认实现就是:
public class DefaultPropositionUpdater implements PropositionUpdater {
public void updateProposition(final PropositionHolder holder, final String action) {
holder.setProposition(holder.getProposition() + action);
}
}
我将保留一个PropositionHolder和PropositionPanelUpdater的默认值给你的想象力;)
现在,这是你的动作监听器:
public class PropositionUpdaterActionListener implements ActionListener {
private PropositionHolder holder;
private PropositionUpdater updater;
private PropositionPanelUpdater panelUpdater;
public PropositionUpdaterActionListener(final PropositionHolder holder, final PropositionUpdater updater, final PropositionPanelUpdater panelUpdater) {
super();
this.holder = holder;
this.updater = updater;
this.panelUpdater = panelUpdater;
}
public void actionPerformed(final ActionEvent evt) {
//Not sure how you *got* the action, but whatever...
updater.updateProposition(holder, action);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panelUpdater.updatePropositionPanel();
}
});
}
}
你没有说你正在谈论多少个按钮。
如果它是一个像棋盘或更少的棋盘,@ juskt的方法是一个很好的方法。
但是,如果你看一些更大的东西,我会用这种方法:
public class MyActionListener {
public void actionPerformed(ActionEvent evt) {
JComponent c = (JComponent)evt.getSoource();
int prop = (Integer)c.getclientProperty("PROPOSITION");
int act = (Integer)c.getclientProperty("ACTION");
SomeClass obj = c.getclientProperty("UPDATE");
prop += act;
// If necessary, clientPut("PROPOSITION", prop);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
obj.updatePropositionPanel();
}
});
}
}
此动作侦听器不保持任何状态。 因此,它的单个实例可用于所有按钮。 对于像Go板(19x19)这样的东西,这可以用于1个对象而不是361个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.