我是Java Swing的初学者。我试图创建一个只有+和 - 的简单计算器。我使用了JButtons,用于“+”和“ - ”,并添加了actionListener来响应每个按钮。但是,我无法理解为什么e.getSource()不起作用。这是动态调度问题吗?我真的很感激帮助!!
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();
}
}
答案 0 :(得分:3)
您通过在构造函数中重新声明它们来遮蔽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("-");
这会使字段为null,并且您在侦听器中的相等测试无法正常工作。解决方案:不要影子!而是使用您已有的字段:
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
。虽然null布局和setBounds()
似乎是Swing新手,比如创建复杂GUI的最简单和最好的方法,但是你创建的Swing GUI越多,你在使用它们时会遇到更严重的困难。 。当GUI调整大小时,他们不会调整组件的大小,他们是增强或维护的皇室女巫,当他们放置在滚动窗格中时,他们完全失败,当他们在所有平台或屏幕分辨率不同时看起来很糟糕原来的。.getSource()
由于您使用了null布局和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());
}
}
显示为:
答案 1 :(得分:0)
在actionPerformed
函数中,您使用JButtons
b1
和b2
声明为Class members
并且没有问题,但您应该请注意,您在JButton
中声明了新的b1
s b2
和Constructor
:
final JButton b1 = new JButton("+");
final JButton b2 = new JButton("-");
ActionListener
附加到这两个,而不是Class members
中您声明为actionPerformed()
的{{1}}。
所以不要遮蔽它们,只需这样做:
b1 = new JButton("+");
b2 = new JButton("-");