如何让多个按钮在 Swing 中单独工作?
How to make multiple buttons work individually in Swing?
我正在尝试开发一个应用程序,我决定学习 Swing 来创建 GUI。以前从来没学过这个,看起来很简单,但是我还没弄明白ActionListener
.
我试图通过在控制台中生成一些调试文本来使按钮响应。
谁能看一看并指出显而易见的地方。
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");
}
}
提前致谢
在 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");
}
}
}
您还应确保花时间通读 How to Use Actions and Laying Out Components Within a Container,这将为您将来省去很多麻烦。
扩张...
像大多数事情一样,要使用 ActionListener
。
您开始使用的方法(而且还不错)的“问题”是 actionPerformed
方法是 public
,因此任何人都可以调用它。这可能不是一个坏主意,但它“泄漏”了可能更好地在内部进行约束的实现细节。
另一个“问题”是所有按钮都使用相同的 ActionListener
。一般来说,这不是一件“坏”事,但它会很快使您的代码变得非常复杂,难以理解和维护。
在解决这些问题之前,我将解决使用对象引用来确定触发了什么的问题(正如我们在上面所做的那样)。同样,这不是一件“坏”事,但它开始限制它的重用,因为你可能有一个按钮、工具栏按钮和菜单按钮都想做同样的事情,重新使用不是很好吗?使用尽可能多的功能?
“动作命令”
使 ActionListener
更易于重用的一种简单方法是利用 actionCommand
属性。这使您可以指定一个 String
,它可用于标识给定的操作,但可能会被用户以多种不同方式触发。
默认情况下,JButton
的 actionCommand
设置为按钮文本,但您可以指定您的按钮以使其更容易。
所以,从...开始...
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
的实例!甜!
匿名类
另一种方法可能会使用“匿名 类”(诡异)。这是一个巧妙的功能,它允许您创建一个 interface
的内联实例(有人会指出我使用的术语是错误的),例如...
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("test 1");
}
});
现在,当调用 actionPerformed
方法时,您可以保证实际触发它的人!无需 actionCommand
或引用检查。
有关详细信息,请参阅 Anonymous Classes。
还有很多其他方法可以使这项工作成功,但我想我可能已经吓到你一个问题了;)
当然,您不需要为所有按钮使用共享 actionListener
。如果每个按钮都有一个,通常可以产生更清晰的代码。所以你可以这样做:
这只是使用一个lambda
为每个按钮注册一个简单的任务。打印语句也可以替换为执行更复杂任务的方法。
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
的私有 class,它可以通过构造函数获取值。
private static class MyActionListener implements ActionListener {
String v;
MyActionListener(String v) {
this.v = v;
}
public void actionPerformed(ActionEvent e) {
System.out.println(v);
}
}
前面的 lambda 示例如下所示。
b.addActionListener(new MyActionListener("test 1"));
b2.addActionListener(new MyActionListener("test 2"));
b3.addActionListener(new MyActionListener("test 3"));
b4.addActionListener(new MyActionListener("test 4"));
所以你有很多选择。
我正在尝试开发一个应用程序,我决定学习 Swing 来创建 GUI。以前从来没学过这个,看起来很简单,但是我还没弄明白ActionListener
.
我试图通过在控制台中生成一些调试文本来使按钮响应。
谁能看一看并指出显而易见的地方。
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");
}
}
提前致谢
在 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");
}
}
}
您还应确保花时间通读 How to Use Actions and Laying Out Components Within a Container,这将为您将来省去很多麻烦。
扩张...
像大多数事情一样,要使用 ActionListener
。
您开始使用的方法(而且还不错)的“问题”是 actionPerformed
方法是 public
,因此任何人都可以调用它。这可能不是一个坏主意,但它“泄漏”了可能更好地在内部进行约束的实现细节。
另一个“问题”是所有按钮都使用相同的 ActionListener
。一般来说,这不是一件“坏”事,但它会很快使您的代码变得非常复杂,难以理解和维护。
在解决这些问题之前,我将解决使用对象引用来确定触发了什么的问题(正如我们在上面所做的那样)。同样,这不是一件“坏”事,但它开始限制它的重用,因为你可能有一个按钮、工具栏按钮和菜单按钮都想做同样的事情,重新使用不是很好吗?使用尽可能多的功能?
“动作命令”
使 ActionListener
更易于重用的一种简单方法是利用 actionCommand
属性。这使您可以指定一个 String
,它可用于标识给定的操作,但可能会被用户以多种不同方式触发。
默认情况下,JButton
的 actionCommand
设置为按钮文本,但您可以指定您的按钮以使其更容易。
所以,从...开始...
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
的实例!甜!
匿名类
另一种方法可能会使用“匿名 类”(诡异)。这是一个巧妙的功能,它允许您创建一个 interface
的内联实例(有人会指出我使用的术语是错误的),例如...
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("test 1");
}
});
现在,当调用 actionPerformed
方法时,您可以保证实际触发它的人!无需 actionCommand
或引用检查。
有关详细信息,请参阅 Anonymous Classes。
还有很多其他方法可以使这项工作成功,但我想我可能已经吓到你一个问题了;)
当然,您不需要为所有按钮使用共享 actionListener
。如果每个按钮都有一个,通常可以产生更清晰的代码。所以你可以这样做:
这只是使用一个lambda
为每个按钮注册一个简单的任务。打印语句也可以替换为执行更复杂任务的方法。
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
的私有 class,它可以通过构造函数获取值。
private static class MyActionListener implements ActionListener {
String v;
MyActionListener(String v) {
this.v = v;
}
public void actionPerformed(ActionEvent e) {
System.out.println(v);
}
}
前面的 lambda 示例如下所示。
b.addActionListener(new MyActionListener("test 1"));
b2.addActionListener(new MyActionListener("test 2"));
b3.addActionListener(new MyActionListener("test 3"));
b4.addActionListener(new MyActionListener("test 4"));
所以你有很多选择。