实现 ActionListener 的 Java 匿名类?
我最近正在做一项编程作业,要求我们用代码实现一个由 UML 图指定的程序。 在某一时刻,该图指定我必须创建一个匿名 JButton,它显示计数(从 1 开始)并在每次单击时递减。 JButton 及其 ActionListener 都必须是匿名的。
我提出了以下解决方案:
public static void main(String[] args) {
JFrame f = new JFrame("frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 400);
f.getContentPane().add(new JButton() {
public int counter;
{
this.counter = 1;
this.setBackground(Color.ORANGE);
this.setText(this.counter + "");
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
counter --;
setText(counter + "");
}
});
}
});
f.setVisible(true);
}
这将添加一个匿名 JButton,然后添加另一个(内部)匿名 ActionListener 来处理事件并根据需要更新按钮的文本。 有更好的解决方案吗? 我很确定我不能声明一个匿名 JButton Implements ActionListener ()
,但是还有另一种更优雅的方法来实现相同的结果吗?
I was recently doing a programming assignment that required us to implement in code a program specified by a UML diagram. At one point, the diagram specified that I had to create an anonymous JButton that displayed a count (starting at one) and decremented each time it was clicked. The JButton and its ActionListener both had to be anonymous.
I came up with the following solution:
public static void main(String[] args) {
JFrame f = new JFrame("frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 400);
f.getContentPane().add(new JButton() {
public int counter;
{
this.counter = 1;
this.setBackground(Color.ORANGE);
this.setText(this.counter + "");
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
counter --;
setText(counter + "");
}
});
}
});
f.setVisible(true);
}
This adds an anonymous JButton, then adds another (inner) anonymous ActionListener to handle events and update the button's text as necessary. Is there a better solution? I'm pretty sure I can't declare an anonymous JButton implements ActionListener ()
, but is there another more elegant way to achieve the same result?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我通常会这样做:
AbstractAction 实现 ActionListener 所以这应该满足任务。
将如此多的代码行压缩在一起可能是不好的做法,但如果您习惯阅读它,那么它可能会非常优雅。
I usually go something like this:
AbstractAction implements ActionListener so this should satisfy the task.
It can be bad practice to squish so many lines of code together, but if you're used to reading it then it can be quite elegant.
它相当丑陋,但您可以使用 ActionListener 方法和匿名类执行以下操作:
为了更轻松地访问计数器,您可以将其移至类的顶层,并从调用 setText 的两个位置访问它。
It's quite ugly, but you could do the following using the ActionListener method and an anonymous class:
To make it easier to access the counter you could move it out to the top level of your class and access it from both places where setText is called.
实现多种类型通常是一个坏主意。
尽管很多糟糕的软件和教程都这样做,但很少需要扩展
JComponent
类。 最近流行的一个习惯用法/黑客是双括号 - 类只是子类,以便为它提供一个实例初始化程序,其作用类似于其他语言中的with
语句。在这种情况下,相关代码可以写为:
如果它变得更复杂,那么您可能想要创建一个外部类(不实现
ActionListener
或扩展JButton) 来处理数据。
另请注意,您应该使用
EventQueue.invokeLater
样板来确保 Swing 组件仅在 AWT EDT 上使用。Implementing multiple types is generally a bad idea.
It is rarely necessary to extend
JComponent
classes, although a lot of bad software and tutorials do it. An idiom/hack that has been gaining ground recently is Double Brace - a class is only subclasses in order to give it an instance initialiser which acts like awith
statement from other languages.In this case, the relevant code can be written as:
If it gets more complex, then you'll probably want to make an outer class (that does not implement
ActionListener
or extendJButton
) to handle the data.Also note, you should be using the
EventQueue.invokeLater
boilerplate to ensure that Swing components are only ever used on the AWT EDT.嗯,有一种更优雅的方法来做到这一点。
不幸的是,它不是核心 Java/Swing 方法。
您可以在 Groovy 中使用 SwingBuilder 来实现相同的结果,使用稍微简洁的语法,例如伪代码:
[http://groovy.codehaus.org/Swing+Builder][1]
不过,我不会在你的作业中使用它,我见过学生确实偏离了规范并对其进行标记,但至少您可以将其作为进一步调查的可能途径。
我认为你目前拥有的一切绝对没问题。
Well there is a much more elegant way to do it.
Unfortunately, it's not a Core Java/Swing approach.
You can use SwingBuilder in Groovy to achieve the same result, using slightly more terse syntax, e.g. psuedo code:
[http://groovy.codehaus.org/Swing+Builder][1]
I wouldn't use this in your assignment though, I've seen students really deviate from the norm and get marked down for it, but at least you can include it as a possible avenue to investigate further.
I think what you have at present is absolutely fine though.
这是仅在家庭作业中被迫完成的不良实践任务之一;-) 不好的事情:
但是,然后..我们无法抗拒,可以吗;-) 这是一个使用 Action 的版本对于前两个问题来说是干净的(或者我认为是这样),与所有其他示例一样不可读(当然,我作弊了:首先实现匿名类,然后让 IDE 执行内联
This is one of bad-practice tasks forced to do in homework only ;-) Bad things:
But, then .. we cannot resist, can we ;-) Here's a version using Action which is clean (or so I think) as to the first two issue, unreadable as all other examples (and I cheated, of course: first implemented the anonymous classes, then let the IDE do the inline