JAVA Swing JButton ActionPerformed方法实现.getSource方法

时间:2017-12-16 19:46:42

标签: 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.*;

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

2 个答案:

答案 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时的样子:

enter image description here

如果您使用布局和匿名侦听器,则代码可能类似于下面的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());
    }
}

显示为:

enter image description here

答案 1 :(得分:0)

actionPerformed函数中,您使用JButtons b1b2声明为Class members并且没有问题,但您应该请注意,您在JButton中声明了新的b1 s b2Constructor

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

ActionListener附加到这两个,而不是Class members中您声明为actionPerformed()的{​​{1}}。

所以不要遮蔽它们,只需这样做:

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