Java 将重复的代码片段简化为 ActionListener 中的函数
Java simplifying a repetitive code snippet to a function within ActionListener
I am wondering what is an elegant and effective way of simplifying the following snippet of code. Since I have many more buttons and their mechanics all behave in the same way, the symmetry of the methods, and the alternation from color.green -> color.red
suggests there may exist a way of simplifying this down to a function?
我一直在为这个设计问题绞尽脑汁,我的编码方式似乎肯定是错误和麻烦的。
游戏框架Class
public class GameFrame extends JFrame{
// (...)
static void initializeComponents(GameFrame frame, GamePanel GamePanel) {
// (...)
ArrayList<JGradientButton> buttons = new ArrayList<JGradientButton>();
Collections.addAll(buttons, b1,b2,b3,b4,b5);
for(JGradientButton button : buttons) {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(button == b1) {
GamePanel.b1Pressed();
} else if (button == b2) {
GamePanel.b2Pressed();
if(GamePanel.removeFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
} else if (button == b3) {
GamePanel.b3Pressed();
if(!GamePanel.collisionFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
} else if (button == b4) {
GamePanel.b4Pressed();
if(!GamePanel.electricFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
} else {
GamePanel.b5Pressed();
if(!GamePanel.gravityFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
}
}
});
}
// (...)
}
我对上面的方法不满意,因为我有很多按钮,而且它们的代码交替使用很容易占用大约 100 行代码。交替的对称性向我表明,可能存在针对此设计的更好方法。
我曾尝试编写一个函数来获取 buttons
列表,但我们用 actionPerformed
覆盖这一事实让我很困惑,我不知道是否真的存在一种方法简化这个。
您可以通过多种方式执行此操作,但其中一种可能是获取您需要的公共状态信息并将其应用于方法,例如...
protected void update(JGradientButton button, boolean state, Color trueState, Color falseState) {
if (state) {
button.color = trueState;
} else {
button.color = falseState;
}
button.repaint();
}
然后您可以使用类似...
的方式来调用它
for (JGradientButton button : buttons) {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (button == b1) {
GamePanel.b1Pressed();
} else if (button == b2) {
GamePanel.b2Pressed();
update(button, GamePanel.removeFlag, Color.green, Color.red);
} else if (button == b3) {
GamePanel.b3Pressed();
update(button, GamePanel.collisionFlag, Color.green, Color.red);
} else if (button == b4) {
GamePanel.b4Pressed();
update(button, GamePanel.electricFlag, Color.green, Color.red);
} else {
GamePanel.b5Pressed();
update(button, GamePanel.gravityFlag, Color.green, Color.red);
}
}
});
我可能还会考虑查看 bXPressed
正在做什么以及它可能能够做什么,以及是否可以将功能移交给他们。
你也可以使用 the Action
API,但问题是,你在看哪个标志?这将需要某种委托查找来确定状态,因此您最终会到达与上述相同的位置。
I am wondering what is an elegant and effective way of simplifying the following snippet of code. Since I have many more buttons and their mechanics all behave in the same way, the symmetry of the methods, and the alternation from
color.green -> color.red
suggests there may exist a way of simplifying this down to a function?
我一直在为这个设计问题绞尽脑汁,我的编码方式似乎肯定是错误和麻烦的。
游戏框架Class
public class GameFrame extends JFrame{
// (...)
static void initializeComponents(GameFrame frame, GamePanel GamePanel) {
// (...)
ArrayList<JGradientButton> buttons = new ArrayList<JGradientButton>();
Collections.addAll(buttons, b1,b2,b3,b4,b5);
for(JGradientButton button : buttons) {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(button == b1) {
GamePanel.b1Pressed();
} else if (button == b2) {
GamePanel.b2Pressed();
if(GamePanel.removeFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
} else if (button == b3) {
GamePanel.b3Pressed();
if(!GamePanel.collisionFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
} else if (button == b4) {
GamePanel.b4Pressed();
if(!GamePanel.electricFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
} else {
GamePanel.b5Pressed();
if(!GamePanel.gravityFlag) {
button.color = Color.green;
} else {
button.color = Color.red;
}
button.repaint();
}
}
});
}
// (...)
}
我对上面的方法不满意,因为我有很多按钮,而且它们的代码交替使用很容易占用大约 100 行代码。交替的对称性向我表明,可能存在针对此设计的更好方法。
我曾尝试编写一个函数来获取 buttons
列表,但我们用 actionPerformed
覆盖这一事实让我很困惑,我不知道是否真的存在一种方法简化这个。
您可以通过多种方式执行此操作,但其中一种可能是获取您需要的公共状态信息并将其应用于方法,例如...
protected void update(JGradientButton button, boolean state, Color trueState, Color falseState) {
if (state) {
button.color = trueState;
} else {
button.color = falseState;
}
button.repaint();
}
然后您可以使用类似...
的方式来调用它for (JGradientButton button : buttons) {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (button == b1) {
GamePanel.b1Pressed();
} else if (button == b2) {
GamePanel.b2Pressed();
update(button, GamePanel.removeFlag, Color.green, Color.red);
} else if (button == b3) {
GamePanel.b3Pressed();
update(button, GamePanel.collisionFlag, Color.green, Color.red);
} else if (button == b4) {
GamePanel.b4Pressed();
update(button, GamePanel.electricFlag, Color.green, Color.red);
} else {
GamePanel.b5Pressed();
update(button, GamePanel.gravityFlag, Color.green, Color.red);
}
}
});
我可能还会考虑查看 bXPressed
正在做什么以及它可能能够做什么,以及是否可以将功能移交给他们。
你也可以使用 the Action
API,但问题是,你在看哪个标志?这将需要某种委托查找来确定状态,因此您最终会到达与上述相同的位置。