如何确定哪个面板上有按下的按钮-应用程序窗口

时间:2018-11-07 20:26:43

标签: java swing jpanel jbutton

在一个20x20的JPanel中,我有一个Tile对象数组(Panel,到平铺的Button)。如果单击按钮1,则发生某事,按下按钮2,即发生某事,等等。

我希望每次单击除第一行中的一个按钮以外的其他按钮时都发生特定功能(第一行按钮均已分配功能,其他380个按钮均未分配功能)。

所以在顶部按钮的情况下,我有代码:

if(e.getSource() == tiles[0][0].button)
    {
    //do stuff
    }
else if(e.getSource() == tiles[0][1].button)
    {
    //do stuff
    }

对于其他按钮,我想要一些类似的东西:

JButton button;
button = e.getSource();
JPanel hostPanel = button.PanelInWhichButtonisContained();

但是我不确定要完成该任务的语法或种类。我真的没有任何代码可以呈现以前的尝试,因为我不确定如何完成此任务,但是我无法在万维网上找到任何东西来帮助我完成此任务。

我目前仅使用默认的应用程序窗口库和类(javax.swing,java.awt等),但是我完全愿意下载外部库。

1 个答案:

答案 0 :(得分:0)

actionPerformed方法中确定诸如按钮按下之类的动作的“来源”通常很困难(幸运的是,几乎没有必要)。

这意味着这是高度可疑的问题:

class ButtonListener implements ActionListener {
    @Override 
    public void actionPerformed(ActionEvent e) {
        // DON'T DO THIS!
        if (e.getSource() == someButton) doThis();
        if (e.getSource() == someOtherButton) doThad();
    }
}

您通常应该执行此操作。

当然,添加演员表并沿一定的容器层次结构走甚至更糟:

// DON'T DO THIS!
Object source = e.getSource();
Component button = (Component)source;
Component parent = button.getParent();
if (parent == somePanel) doThis();
if (parent == someOtherPanel) doThat();

在几乎所有情况下,将监听器附加到按钮的 上都更加灵活,美观,这意味着知道按钮的含义应该做。

对于单个按钮,可以使用匿名内部类通过老式方法解决:

class Gui {

    void create() {
        JButton startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {
            @Override 
            public void actionPerformed(ActionEvent e) {
                startSomething();
            }
        });
    }

    private void startSomething() { ... }
}

在Java 8中使用lambda表达式可以写得更简洁:

class Gui {

    void create() {
        JButton startButton = new JButton("Start");
        startButton.addActionListener(e -> startSomething());
    }

    private void startSomething() { ... }
}

(一个旁注:我认为,无论如何,仅在ActionListener实现中只调用一个方法是一种好习惯。actionPerformed方法不应包含很多代码行,尤其是不应包含“业务逻辑”。应该为按钮的作用(例如,如上例中的startSomething)使用专用的方法


对于数组中包含的按钮(如您的问题示例中所示),有一个巧妙的技巧可以保留有关被单击按钮的信息:

class Gui {

    JButton buttons[];

    void create() {

        buttons = new JButton[5];
        for (int i=0; j<buttons.length; i++) { 
            int index = i;
            buttons[i] = new JButton("Button " + i);
            buttons[i].addActionListener(e -> clickedButton(index));
        }
    }

    private void clickedButton(int index) { 
        System.out.println("Clicked button at index " + index);
    }
}

在许多情况下,您甚至不必再保留JButton buttons[]数组。通常,您可以只创建按钮,将它们添加到某个面板,然后只对传递给index方法的clickedButton感兴趣。 (不过,button[]数组在某些情况下可能是必需的,例如,如果您想在单击按钮后更改按钮的标签)。