如何确定哪个面板上有按下的按钮-应用程序窗口 [英] How to determine which panel holds a button that was pressed - Application Window

查看:88
本文介绍了如何确定哪个面板上有按下的按钮-应用程序窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an array of Tile objects (Panel, Button to a tile) in a JPanel, 20x20. If button 1 is clicked, a thing happens, button 2 is pressed, a thing happens, etc.

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

I want a specific function to happen every time a button other than one in the top row is clicked (the top row of buttons all have functions assigned, the other 380 buttons do not have assigned functions).

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

So in the top buttons' cases I have the code:

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

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

For the other buttons, I want something along the lines of:

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

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

but I'm not sure what the syntax or what sort I would to do achieve that task. I don't really have any code to present prior attempts because I'm not sure how to approach this task, but I haven't been able to find anything on the World Wide Web to help me in this task.

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

I'm currently just using default application window libraries and classes (javax.swing, java.awt, etc) but I'm completely open to downloading external libraries.

推荐答案

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

Determining the "source" of an action like a button press in the actionPerformed method is usually brittle (and fortunately, hardly ever necessary).

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

This means that this is highly questionable:

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

您通常应该执行此操作.

You should usually NOT do this.

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

And of course, it's even worse to add casts and walk up some container hierarchy:

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


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


In basically all cases, it is far more flexible and elegant to attach a listener to the button that is specific for the button - meaning that it knows what the button should do.

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

For individual buttons, this can be solved the old-fashioned way, using an anonymous inner class:

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表达式可以写得更简洁:

The same can be written far more concisely using lambda expressions with Java 8:

class Gui {

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

    private void startSomething() { ... }
}

(一个旁注:我认为,无论如何,仅在ActionListener实现中仅调用一个方法是一种好习惯.actionPerformed方法不应包含很多代码行,尤其是不应包含业务逻辑".应该为按钮的作用提供专门的方法-例如,如上面的示例中的startSomething所示.

(A side note: I consider it as a good practice to only call a single method in the ActionListener implementation anyhow. The actionPerformed method should not contain many lines of code, and particularly no "business logic". There should be a dedicated method for what the button does - for example, to startSomething, as in the example above)

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

For buttons that are contained in arrays, as in the example in your question, there is a neat trick to retain the information about the button that was clicked:

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[]数组.通常,您可以只创建按钮,将它们添加到某些面板,然后只对传递给clickedButton方法的index感兴趣. (不过,在某些情况下button[]数组可能是必需的,例如,如果您想在单击按钮后更改按钮的标签).

In many cases, you then don't even have to keep the JButton buttons[] array any more. Often you can just create the buttons, add them to some panel, and then are only interested in the index that is passed to the clickedButton method. (The button[] array may be necessary in some cases, though - for example, if you want to change the label of a button after it was clicked).

这篇关于如何确定哪个面板上有按下的按钮-应用程序窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆