Java 将重复的代码片段简化为 ActionListener 中的函数 游戏框架类

问题描述

我想知道简化以下代码片段的优雅而有效的方法是什么。由于我有更多按钮并且它们的机制都以相同的方式运行,因此方法的对称性以及 color.green -> color.red 的交替表明可能存在一种将其简化为函数方法

我已经在这个设计问题上摸索了一段时间,我编码它的方式似乎绝对是错误和繁琐的。

游戏框架类

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 覆盖的事实让我很困惑,我不知道是否真的存在一种简化方法这个。

解决方法

您可以通过多种方式执行此操作,但一种可能是获取您需要的公共状态信息并将其应用于方法,例如...

User

然后你可以使用类似...的东西来调用它

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.red); } else if (button == b4) { GamePanel.b4Pressed(); update(button,GamePanel.electricFlag,Color.red); } else { GamePanel.b5Pressed(); update(button,GamePanel.gravityFlag,Color.red); } } }); 正在做什么以及它可以做什么,以及是否可以将功能移交给他们。

您也可以使用 the Action API,但问题是,您在看哪个标志?这将需要某种委托查找来确定状态,因此您最终会在与上述相同的地方。