JAVA Swing JButton ActionPerformed方法实现.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.

我是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();
    }
}

您正在通过在构造函数中重新声明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
    。虽然空布局和
    setBounds()
    可能会像创建复杂GUI的最简单和最好的方式一样吸引新手,但您创建的GUI越多,在使用它们时遇到的困难就越严重。当GUI调整大小时,它们不会调整您的组件的大小,它们是一个需要增强或维护的皇家女巫,当它们放置在滚动窗格中时会完全失败,当在所有平台或屏幕分辨率与原始分辨率不同的情况下查看时,它们看起来非常糟糕
  • 考虑为侦听器使用匿名内部类。然后您甚至不需要使用
    .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
    。虽然空布局和
    setBounds()
    可能会像创建复杂GUI的最简单和最好的方式一样吸引新手,但您创建的GUI越多,在使用它们时遇到的困难就越严重。当GUI调整大小时,它们不会调整您的组件的大小,它们是一个需要增强或维护的皇家女巫,当它们放置在滚动窗格中时会完全失败,当在所有平台或屏幕分辨率与原始分辨率不同的情况下查看时,它们看起来非常糟糕
  • 考虑为侦听器使用匿名内部类。然后您甚至不需要使用
    .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
s
b1
b2

 final JButton b1 = new JButton("+"); 
 final JButton b2 = new JButton("-");
ActionListener
附加到这两个类,而不是您在
actionPerformed()
中使用的声明为
类成员的类

因此,与其跟踪他们,不如这样做:

b1 = new JButton("+"); 
b2 = new JButton("-");

actionPerformed
函数中,您正在使用声明为
类成员的
JButtons
b1
b2
,这没有问题,但是您应该注意,您在
构造函数中声明了新的
JButton
s
b1
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。更多信息,请阅读。