如何用一个替换十几个动作监听器?
How to replace a dozen action listeners with one?
我有 9 大块形式相同的代码,例如:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...有 9 个相应的链接代码块,如下所示:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
...以及大量类似的重复代码块
对于 FocusListener
和 MouseListener
。
我试图通过分配来减少代码行数
按钮的文本到它的动作命令并使用这个:
public void actionPerformed(ActionEvent e)
{
String c = e.getActionCommand();
switch (c) {
case "Clear output": btnClearOutputActionPerformed(e); break;
case "Search": btnSearchActionPerformed(e); break;
case "Exit": btnExitActionPerformed(e); break;
...
}
}
它有效,但并没有好多少。还是重复的。寻找优雅。
我不敢相信以下方法甚至可以编译,但它不起作用,因为 doClick()
递归调用该方法。我天真地希望 doClick()
会执行方法 btnPatternMouseClickedActionPerformed()
.
public void actionPerformed(ActionEvent e){
Component[] c ;
c = theFrame.getComponents();
JButton b;
for(Component x: c)
{
if(x instanceof JButton)
{
b = (JButton) x;
if(b.getText().equals(e.getActionCommand()))
{
b.doClick(); // want it to execute code elsewhere
return;
}
}
}
}
起初我以为上面的方法很接近。现在我要放弃了。
我有三个问题:
(1) 有没有办法减少如前两段所示的重复代码块?
(1a) 上面最后一个方法是否关闭?可以轻松修复吗?
(2) 是否会有一种类似于上述 actionPerformed
方法(使用 switch
的方法)的技术来替换 FocusListener
和 MouseListener
的代码块?浪费时间实施?
你可以改变这个:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...有 9 个相应的链接代码块,如下所示:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
对此:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// same code that was in the btnExitActionPerformed method.
}
});
但也许更好的方法是将您的 "control" 代码(监听器中的代码)与您的 "view" 代码(您的 GUI)分开,但是如何做到这一点取决于您的问题和当前代码库。
编辑
你问:
I will blame Swing GUI builder for that (bad?) habit.
还不错,而且肯定比让 GUI classes 实现侦听器接口要好很多。
Why does Swing do that?? Why does Swing do a LOT of what it does!!
我不确定你在这里具体指的是什么。
So about "even better": are you saying to separate the listeners into another class file? And are you suggesting that coconuts migr~~...
是的,是的。事实上,控件 - 侦听器部分可以由多个 class 组成,但它们都可能用于单个主控件 class。
I mean, that I should abandon the last method in my question?
是的。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class Example implements ActionListener{
JButton buttons[] = new JButton[12];
public Example(){
for(int c=0; c<buttons.length; c++){
buttons[c]=new JButton("I am button"+c);
buttons[c].addActionListener(this);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == buttons[0]){}
if(e.getSource() == buttons[1]){}
if(e.getSource() == buttons[2]){}
if(e.getSource() == buttons[3]){}
if(e.getSource() == buttons[4]){}
if(e.getSource() == buttons[5]){}
if(e.getSource() == buttons[6]){}
if(e.getSource() == buttons[7]){}
//....
}
}
你的代码不够优雅?
其他:
例如,如果您有同一个团队中的按钮,例如:
最好有一个 class(java 对象),然后取对象并制作按钮。
public class TVButton implements ActionListener{
public TVButton(String name,String whatever){
}
@Override
public void actionPerformed(ActionEvent e){
//actionFor this button
}
}
我有 9 大块形式相同的代码,例如:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...有 9 个相应的链接代码块,如下所示:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
...以及大量类似的重复代码块
对于 FocusListener
和 MouseListener
。
我试图通过分配来减少代码行数 按钮的文本到它的动作命令并使用这个:
public void actionPerformed(ActionEvent e)
{
String c = e.getActionCommand();
switch (c) {
case "Clear output": btnClearOutputActionPerformed(e); break;
case "Search": btnSearchActionPerformed(e); break;
case "Exit": btnExitActionPerformed(e); break;
...
}
}
它有效,但并没有好多少。还是重复的。寻找优雅。
我不敢相信以下方法甚至可以编译,但它不起作用,因为 doClick()
递归调用该方法。我天真地希望 doClick()
会执行方法 btnPatternMouseClickedActionPerformed()
.
public void actionPerformed(ActionEvent e){
Component[] c ;
c = theFrame.getComponents();
JButton b;
for(Component x: c)
{
if(x instanceof JButton)
{
b = (JButton) x;
if(b.getText().equals(e.getActionCommand()))
{
b.doClick(); // want it to execute code elsewhere
return;
}
}
}
}
起初我以为上面的方法很接近。现在我要放弃了。
我有三个问题:
(1) 有没有办法减少如前两段所示的重复代码块?
(1a) 上面最后一个方法是否关闭?可以轻松修复吗?
(2) 是否会有一种类似于上述 actionPerformed
方法(使用 switch
的方法)的技术来替换 FocusListener
和 MouseListener
的代码块?浪费时间实施?
你可以改变这个:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...有 9 个相应的链接代码块,如下所示:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
对此:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// same code that was in the btnExitActionPerformed method.
}
});
但也许更好的方法是将您的 "control" 代码(监听器中的代码)与您的 "view" 代码(您的 GUI)分开,但是如何做到这一点取决于您的问题和当前代码库。
编辑
你问:
I will blame Swing GUI builder for that (bad?) habit.
还不错,而且肯定比让 GUI classes 实现侦听器接口要好很多。
Why does Swing do that?? Why does Swing do a LOT of what it does!!
我不确定你在这里具体指的是什么。
So about "even better": are you saying to separate the listeners into another class file? And are you suggesting that coconuts migr~~...
是的,是的。事实上,控件 - 侦听器部分可以由多个 class 组成,但它们都可能用于单个主控件 class。
I mean, that I should abandon the last method in my question?
是的。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class Example implements ActionListener{
JButton buttons[] = new JButton[12];
public Example(){
for(int c=0; c<buttons.length; c++){
buttons[c]=new JButton("I am button"+c);
buttons[c].addActionListener(this);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == buttons[0]){}
if(e.getSource() == buttons[1]){}
if(e.getSource() == buttons[2]){}
if(e.getSource() == buttons[3]){}
if(e.getSource() == buttons[4]){}
if(e.getSource() == buttons[5]){}
if(e.getSource() == buttons[6]){}
if(e.getSource() == buttons[7]){}
//....
}
}
你的代码不够优雅?
其他: 例如,如果您有同一个团队中的按钮,例如: 最好有一个 class(java 对象),然后取对象并制作按钮。
public class TVButton implements ActionListener{
public TVButton(String name,String whatever){
}
@Override
public void actionPerformed(ActionEvent e){
//actionFor this button
}
}