如何在swingx中使多个按钮单独工作?

bjp0bcyl  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(366)

我正在尝试开发一个应用程序,我决定学习swingx来创建gui。我以前从来没有学过这个,看起来很简单,但我还没有弄清楚。
我试图通过在控制台中生成一些调试文本来让按钮做出响应。
有人能看一下并指出明显的问题吗。

package GUI;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;  
public class MainMenu implements ActionListener{  
JFrame f;
JButton b,b1,b2,b3,b4;

MainMenu(){  
f=new JFrame();//creating instance of JFrame  

JButton b=new JButton("click1");//creating instance of JButton  
b.setBounds(130,50,100, 40);
JButton b2=new JButton("click2");//creating instance of JButton  
b2.setBounds(130,150,100, 40);
JButton b3=new JButton("click3");//creating instance of JButton  
b3.setBounds(130,250,100, 40);
JButton b4=new JButton("click4");//creating instance of JButton  
b4.setBounds(130,350,100, 40);

f.add(b);//adding button in JFrame  
f.add(b2);
f.add(b3);
f.add(b4);
f.setSize(400,500);//400 width and 500 height  
f.setLayout(null);//using no layout managers  
f.setVisible(true);//making the frame visible  
}  

public static void main(String[] args) {  
new MainMenu();  
    }

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b)
        System.out.println("test 1");
     else if (e.getSource() == b2)
         System.out.println("test 2");
     else if
        (e.getSource() == b3)
         System.out.println("test 3");
     else if
        (e.getSource() == b4)
        System.out.println("test 4");

}  
}

提前谢谢

wxclj1h5

wxclj1h51#

在swing中,“监听器”基于一个简单的概念,称为“观察者模式”。在对象上注册的兴趣在其插入的内容发生时被另一个对象通知。
在您的情况下,当按钮被“操作”时。
但是,在你解决这个问题之前,你需要解决另一个问题。
你在跟踪你的变量。。。

public class MainMenu implements ActionListener {

    JFrame f;
    JButton b, b1, b2, b3, b4;

    MainMenu() {
        JButton b = new JButton("click1");//creating instance of JButton  
        JButton b2 = new JButton("click2");//creating instance of JButton  
        JButton b3 = new JButton("click3");//creating instance of JButton  
        JButton b4 = new JButton("click4");//creating instance of JButton  
    }
}

你已经宣布 b , b1 , b2 , b3 以及 b4 作为 MainMenu ,但在构造函数中已将它们重新声明为局部变量,其上下文仅在构造函数中可用。这意味着,如果任何其他方法尝试引用这些属性,它们将发现它们是 null 现在我们已经发现了这个问题,我们可以纠正它,并添加神奇的酱汁,使您的代码工作。。。

b = new JButton("click1");//creating instance of JButton  
b2 = new JButton("click2");//creating instance of JButton  
b3 = new JButton("click3");//creating instance of JButton  
b4 = new JButton("click4");//creating instance of JButton  

b.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);

在这里,我们只是说,“巴顿,告诉我你什么时候行动”

示例。。。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class MainMenu implements ActionListener {

    JFrame f;
    JButton b, b1, b2, b3, b4;

    MainMenu() {
        f = new JFrame();//creating instance of JFrame  

        b = new JButton("click1");//creating instance of JButton  
        b2 = new JButton("click2");//creating instance of JButton  
        b3 = new JButton("click3");//creating instance of JButton  
        b4 = new JButton("click4");//creating instance of JButton  

        b.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
        b4.addActionListener(this);

        JPanel content = new JPanel(new GridBagLayout());
        content.setBorder(new EmptyBorder(10, 10, 10, 10));
        f.setContentPane(content);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(10, 0, 10, 0);
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        f.add(b, gbc);
        f.add(b2, gbc);
        f.add(b3, gbc);
        f.add(b4, gbc);

        f.pack();
        f.setVisible(true);//making the frame visible  
    }

    public static void main(String[] args) {
        new MainMenu();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == b) {
            System.out.println("test 1");
        } else if (e.getSource() == b2) {
            System.out.println("test 2");
        } else if (e.getSource() == b3) {
            System.out.println("test 3");
        } else if (e.getSource() == b4) {
            System.out.println("test 4");
        }

    }
}

您还应该确保花时间通读如何在容器中使用动作和布局组件,这将在将来为您节省大量的麻烦。

扩展。。。

像大多数事情一样,有不止一个使用 ActionListener .
你开始使用的方法的“问题”是 actionPerformed 方法是 public ,所以任何人都可以称之为。这可能不是一个坏主意,但它“泄露”了实现细节,而这些细节可能更好地在内部约束。
另一个“问题”是所有的按钮使用相同的 ActionListener . 一般来说,这不是一件“坏事”,但它会使代码变得非常复杂,难以理解和维护。
在解决这些问题之前,我将解决使用对象引用来确定触发了什么的问题(正如我们上面所做的)。同样,这不是一件“坏事”,但它开始限制它的重用,因为你可以有一个按钮,工具栏按钮和菜单按钮都想做同样的事情,这不是很好的重用尽可能多的功能吗?

“行动命令”

一种简单的方法 ActionListener 更可重用的,是利用 actionCommand 财产。这允许您指定 String 它可以用来识别一个给定的动作,但是用户可以通过多种不同的方式触发它。
默认情况下 JButtonactionCommand 设置为按钮文本,但您可以指定您的按钮以使其更简单。
所以,从。。。

b = new JButton("click1");//creating instance of JButton

然后使用类似于。。。

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand().equals("click1")) {
        System.out.println("test 1");
    } //...
}

确定何时触发动作。关键是,要将逻辑解耦。此实现不再依赖于(耦合到)的示例 b ! 太好了!

匿名类

另一种方法可能是使用“匿名类”(spooky)。这是一个整洁的特性,它允许您创建一个 interface ,例如。。。

b.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("test 1");
    }
});

现在,当 actionPerformed 方法被调用时,您可以确定是谁触发了它!不用了 actionCommand 或引用检查。
有关详细信息,请参见匿名类。
有很多其他的方法可以让这个工作,但我想我可能已经吓到你一个问题;)

vc9ivgsu

vc9ivgsu2#

当然,您不需要使用共享 actionListener 所有的按钮。如果每个按钮都有一个,那么通常会产生更干净的代码。因此您可以执行以下操作:
这只需要一个 lambda 为每个按钮注册一个简单任务。print语句也可以替换为执行更复杂任务的方法。

b.addActionListener(ae->System.out.println("test 1"));
b2.addActionListener(ae->System.out.println("test 2"));
b3.addActionListener(ae->System.out.println("test 3"));
b4.addActionListener(ae->System.out.println("test 4"));

然后有一个私有类实现 ActionListener 可以通过构造函数获取值。

private static class MyActionListener implements ActionListener {
    String v;
    MyActionListener(String v) {
        this.v = v;
    }
    public void actionPerformed(ActionEvent e) {
        System.out.println(v);
    }
}

前面的lambdas示例如下所示。

b.addActionListener(new MyActionListener("test 1"));
b2.addActionListener(new MyActionListener("test 2"));
b3.addActionListener(new MyActionListener("test 3"));
b4.addActionListener(new MyActionListener("test 4"));

所以你有很多选择。

相关问题