JAVA Swing JButton ActionPerformed方法实现.getSource方法
我是Java Swing的初学者。我试图创建一个只有+和-。我使用JButtons,表示“+”和“-”,并添加了actionListener来响应每个按钮。然而,我真的不明白为什么e.getSource()不能工作。这是一个动态调度问题吗?我真的非常感谢你的帮助JAVA Swing JButton ActionPerformed方法实现.getSource方法,java,swing,Java,Swing,我是Java Swing的初学者。我试图创建一个只有+和-。我使用JButtons,表示“+”和“-”,并添加了actionListener来响应每个按钮。然而,我真的不明白为什么e.getSource()不能工作。这是一个动态调度问题吗?我真的非常感谢你的帮助 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.*; import javax.swing.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.*;
import javax.swing.*;
class MenuExample implements ActionListener {
// JMenu menu1, menu2, menu3;
// JMenuItem i1, i2, i3, i4, i5;
JTextArea t1, t2;
JTextField t3;
JButton b1, b2;
MenuExample() {
JFrame f = new JFrame("Menu and MenuItem EX");
final JButton b1 = new JButton("+");
final JButton b2 = new JButton("-");
t3 = new JTextField();t3.setBounds(50, 350, 200, 30); t3.setEditable(false);
t1 = new JTextArea(); t1.setBounds(50,100,200,30);
t2 = new JTextArea(); t2.setBounds(50,250,200,30);
b1.addActionListener(this);
b2.addActionListener(this);
b1.setBounds(50, 450, 30, 30); b2.setBounds(100, 450, 30, 30);
f.add(b1); f.add(b2);f.add(t1); f.add(t2); f.add(t3);
f.setSize(800, 800);
f.setLayout(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
JButton button;
int answer=0;
String s1 = t1.getText();
String s2 = t2.getText();
int a = Integer.parseInt(s1);
int b = Integer.parseInt(s2);
Object source = e.getSource();
if (source instanceof JButton) {
button = (JButton) source;
System.out.println("called here at least?");
System.out.println(button.getClass());
if (button == b1) {
answer = a + b;
}
else if (button == b2) {
answer = a - b;
}
}
String result = String.valueOf(answer);
t3.setText(result);
}
}
public class JMenuPractice {
public static void main (String[] args) {
new MenuExample();
}
}
您正在通过在构造函数中重新声明b1和b2 JButton字段来隐藏它们:
class MenuExample implements ActionListener {
JTextArea t1, t2;
JTextField t3;
JButton b1, b2; // these stay null!!!
MenuExample() {
JFrame f = new JFrame("Menu and MenuItem EX");
// Don't re-declare the variables here!
final JButton b1 = new JButton("+");
final JButton b2 = new JButton("-");
这会使字段为空,侦听器中的相等性测试将无法工作。解决方法:不要阴影!而是使用您已有的字段:
class MenuExample implements ActionListener {
JTextArea t1, t2;
JTextField t3;
JButton b1, b2; // these are no longer null
MenuExample() {
JFrame f = new JFrame("Menu and MenuItem EX");
// final JButton b1 = new JButton("+");
// final JButton b2 = new JButton("-");
b1 = new JButton("+");
b2 = new JButton("-");
注意到巨大的差异吗
其他问题:
- 不要使用空布局和
。虽然空布局和setBounds
可能会像创建复杂GUI的最简单和最好的方式一样吸引新手,但您创建的GUI越多,在使用它们时遇到的困难就越严重。当GUI调整大小时,它们不会调整您的组件的大小,它们是一个需要增强或维护的皇家女巫,当它们放置在滚动窗格中时会完全失败,当在所有平台或屏幕分辨率与原始分辨率不同的情况下查看时,它们看起来非常糟糕setBounds()
- 考虑为侦听器使用匿名内部类。然后您甚至不需要使用
.getSource()
setBounds
,因此在我运行GUI时,它是这样的:
如果使用布局和匿名侦听器,代码可能与下面的GUI类似。请注意,我喜欢使用JSpinners而不是JTextFields进行输入,因为这将输入限制为数字:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.*;
@SuppressWarnings("serial")
public class SimpleCalc extends JPanel {
private static final int GAP = 4;
private JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0, -1000, 1000, 1));
private JSpinner spinner2 = new JSpinner(new SpinnerNumberModel(0, -1000, 1000, 1));
private JTextField resultField = new JTextField(10);
private JButton addButton = new JButton("+");
private JButton subtractButton = new JButton("-");
public SimpleCalc() {
// add anonymous listeners to each JButton
addButton.addActionListener(e -> add());
subtractButton.addActionListener(e -> subtract());
// put both buttons within a JPanel that uses grid layout
// 1 row, variable number of columns, gap between components
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
buttonPanel.add(addButton);
buttonPanel.add(subtractButton);
resultField.setFocusable(false);
resultField.setEditable(false);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
// use GridBagLayout
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
// start at x position is 0, and stay there
gbc.gridx = 0;
// y position increments each time
gbc.gridy = GridBagConstraints.RELATIVE;
// stretch components horizontally not vertically
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
// gap between componentns
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
add(spinner1, gbc);
add(spinner2, gbc);
add(resultField, gbc);
add(buttonPanel, gbc);
}
public void add() {
int value1 = (int) spinner1.getValue();
int value2 = (int) spinner2.getValue();
int result = value1 + value2;
resultField.setText(String.valueOf(result));
}
public void subtract() {
int value1 = (int) spinner1.getValue();
int value2 = (int) spinner2.getValue();
int result = value1 - value2;
resultField.setText(String.valueOf(result));
}
private static void createAndShowGui() {
SimpleCalc mainPanel = new SimpleCalc();
JFrame frame = new JFrame("SimpleCalc");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
显示为:
您正在通过在构造函数中重新声明b1和b2 JButton字段来隐藏它们:
class MenuExample implements ActionListener {
JTextArea t1, t2;
JTextField t3;
JButton b1, b2; // these stay null!!!
MenuExample() {
JFrame f = new JFrame("Menu and MenuItem EX");
// Don't re-declare the variables here!
final JButton b1 = new JButton("+");
final JButton b2 = new JButton("-");
这会使字段为空,侦听器中的相等性测试将无法工作。解决方法:不要阴影!而是使用您已有的字段:
class MenuExample implements ActionListener {
JTextArea t1, t2;
JTextField t3;
JButton b1, b2; // these are no longer null
MenuExample() {
JFrame f = new JFrame("Menu and MenuItem EX");
// final JButton b1 = new JButton("+");
// final JButton b2 = new JButton("-");
b1 = new JButton("+");
b2 = new JButton("-");
注意到巨大的差异吗
其他问题:
- 不要使用空布局和
。虽然空布局和setBounds
可能会像创建复杂GUI的最简单和最好的方式一样吸引新手,但您创建的GUI越多,在使用它们时遇到的困难就越严重。当GUI调整大小时,它们不会调整您的组件的大小,它们是一个需要增强或维护的皇家女巫,当它们放置在滚动窗格中时会完全失败,当在所有平台或屏幕分辨率与原始分辨率不同的情况下查看时,它们看起来非常糟糕setBounds()
- 考虑为侦听器使用匿名内部类。然后您甚至不需要使用
.getSource()
setBounds
,因此在我运行GUI时,它是这样的:
如果使用布局和匿名侦听器,代码可能与下面的GUI类似。请注意,我喜欢使用JSpinners而不是JTextFields进行输入,因为这将输入限制为数字:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.*;
@SuppressWarnings("serial")
public class SimpleCalc extends JPanel {
private static final int GAP = 4;
private JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0, -1000, 1000, 1));
private JSpinner spinner2 = new JSpinner(new SpinnerNumberModel(0, -1000, 1000, 1));
private JTextField resultField = new JTextField(10);
private JButton addButton = new JButton("+");
private JButton subtractButton = new JButton("-");
public SimpleCalc() {
// add anonymous listeners to each JButton
addButton.addActionListener(e -> add());
subtractButton.addActionListener(e -> subtract());
// put both buttons within a JPanel that uses grid layout
// 1 row, variable number of columns, gap between components
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
buttonPanel.add(addButton);
buttonPanel.add(subtractButton);
resultField.setFocusable(false);
resultField.setEditable(false);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
// use GridBagLayout
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
// start at x position is 0, and stay there
gbc.gridx = 0;
// y position increments each time
gbc.gridy = GridBagConstraints.RELATIVE;
// stretch components horizontally not vertically
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
// gap between componentns
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
add(spinner1, gbc);
add(spinner2, gbc);
add(resultField, gbc);
add(buttonPanel, gbc);
}
public void add() {
int value1 = (int) spinner1.getValue();
int value2 = (int) spinner2.getValue();
int result = value1 + value2;
resultField.setText(String.valueOf(result));
}
public void subtract() {
int value1 = (int) spinner1.getValue();
int value2 = (int) spinner2.getValue();
int result = value1 - value2;
resultField.setText(String.valueOf(result));
}
private static void createAndShowGui() {
SimpleCalc mainPanel = new SimpleCalc();
JFrame frame = new JFrame("SimpleCalc");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
显示为:
在
actionPerformed
函数中,您正在使用JButtons
b1
和b2
声明为类成员,这没有问题,但您应该注意,您在构造函数中声明了新的JButton
sb1
和b2
:
final JButton b1 = new JButton("+");
final JButton b2 = new JButton("-");
ActionListener
附加到这两个类,而不是您在actionPerformed()
中使用的声明为类成员的类
因此,与其跟踪他们,不如这样做:
b1 = new JButton("+");
b2 = new JButton("-");
在actionPerformed
函数中,您正在使用声明为类成员的JButtons
b1
和b2
,这没有问题,但是您应该注意,您在构造函数中声明了新的JButton
sb1
和b2
:
final JButton b1 = new JButton("+");
final JButton b2 = new JButton("-");
ActionListener
附加到这两个类,而不是您在actionPerformed()
中使用的声明为类成员的类
因此,与其跟踪他们,不如这样做:
b1 = new JButton("+");
b2 = new JButton("-");
非常感谢你的回答!!对于使用setBounds和null布局的替代方案,您会使用布局管理器吗?喜欢flowLayout和BorderLayout吗?@ChatSev:是的,你可以使用BorderLayout和flowLayout。我经常嵌套JPanel,每个都使用自己的布局。上面的示例同时使用GridLayout和GridBagLayout。阅读更多。非常感谢这个有用的答案!!对于使用setBounds和null布局的替代方案,您会使用布局管理器吗?喜欢flowLayout和BorderLayout吗?@ChatSev:是的,你可以使用BorderLayout和flowLayout。我经常嵌套JPanel,每个都使用自己的布局。上面的示例同时使用GridLayout和GridBagLayout。更多信息,请阅读。