如何在AWT中找到一个按钮的源代码(计算器作业)

9

我们被要求制作一个简单的GUI计算器,我使用getSource()来检测按钮,因为这是他们教给我们的。它通过输入第一个和第二个值然后选择操作来工作,它有效。但我犯了一个错误,因为他们希望我们做的是数字也应该是按钮,就像真正的计算器一样。所以我该如何使用getSource()获取每个按钮的值?例如当我按下1和2按钮时等于3。这是我所做的。

import java.awt.*;
import java.awt.event.*;

public class SimpleCalculator implements ActionListener
{
    // containers
    private Frame f;
    private Panel p1, p2, p3, p4;

    // components
    private Label l1, l2, l3;
    private TextField tf1, tf2, tf3;
    private Button bAdd, bSub, bMul, bDiv, bClear;

    public SimpleCalculator()
    {
        f = new Frame("My First GUI App");

        p1 = new Panel();
        p2 = new Panel();
        p3 = new Panel();
        p4 = new Panel();

        l1 = new Label("First: ");
        l2 = new Label("Second: ");
        l3 = new Label("Result: ");

        tf1 = new TextField(15);
        tf2 = new TextField(15);
        tf3 = new TextField(15);

        bAdd = new Button("+");
        bSub = new Button("-");
        bMul = new Button("*");
        bDiv = new Button("/");
        bClear = new Button("C");
    }
    public void launchFrame()
    {
        // use default layout manager of the Panel (FlowLayout)
        p1.add(l1);
        p1.add(tf1);

        p2.add(l2);
        p2.add(tf2);

        p3.add(l3);
        p3.add(tf3);

        p4.add(bAdd);
        p4.add(bSub);
        p4.add(bMul);
        p4.add(bDiv);
        p4.add(bClear);

        // change the layout manager of the Frame, 
        // use GridLayout(4, 1)
        f.setLayout(new GridLayout(4, 1));

        f.add(p1);
        f.add(p2);
        f.add(p3);
        f.add(p4);

        f.pack();
        f.setVisible(true);

        // register event handlers
        bAdd.addActionListener(this);
        bSub.addActionListener(this);
        bMul.addActionListener(this);
        bDiv.addActionListener(this);
        bClear.addActionListener(this);

        f.addWindowListener(new MyCloseButtonHandler());
    }
    // override the actionPerformed method
    public void actionPerformed(ActionEvent ae)
    {
        Object source = ae.getSource();
        double num1, num2, result = 0.0;

        if (tf1.getText() != null && tf2.getText() != null)
        {
            num1 = Double.parseDouble(tf1.getText());
            num2 = Double.parseDouble(tf2.getText());

            if (source == bAdd)
                result = num1 + num2;
            else if (source == bSub)
                result = num1 - num2;
            else if (source == bMul)
                result = num1 * num2;
            else if (source == bDiv)
                result = num1 / num2;
            else if (source == bClear)
            {
                tf1.setText("0.0");
                tf2.setText("0.0");
                tf3.setText("0.0");
            }
            else {}
            // tf3.setText(new Double(result).toString());
            tf3.setText("" + result);
        }
    }
    private class MyCloseButtonHandler extends WindowAdapter
    {
        public void windowClosing(WindowEvent we)
        {
            System.exit(0);
        }
    }
    public static void main(String args[])
    {
        SimpleCalculator sc = new SimpleCalculator();
        sc.launchFrame();
    }
}

哪一行/部分代码出了问题? - Kashir hasnain
2个回答

19

我会倾向于为每个数字按钮和运算符按钮添加文本到一个名为“输入/输出”的文本字段中。

同时还要有一个等于号=的按钮。当激活=按钮时,调用ScriptEngine来计算I/O文本字段的内容,并将结果写回文本字段。

例如:

Calculet input = Calculet output

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.ArrayList;

// script package introduced in Java 1.6
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

class ScriptEngineCalculator implements ActionListener, KeyListener {

    private final JTextField io = new JTextField(15);
    private final ArrayList<JButton> controls = new ArrayList<>();
    private final JPanel ui = new JPanel(new BorderLayout(2, 2));
    private ScriptEngine engine;

    ScriptEngineCalculator() {
        initUI();
    }

    public final void initUI() {
        // obtain a reference to the JS engine
        engine = new ScriptEngineManager().getEngineByExtension("js");

        JPanel text = new JPanel(new GridLayout(0, 1, 3, 3));
        ui.add(text, BorderLayout.PAGE_START);
        Font font = io.getFont();
        font = font.deriveFont(font.getSize() * 1.8f);
        io.setFont(font);
        io.setHorizontalAlignment(SwingConstants.TRAILING);
        io.setFocusable(false);
        text.add(io);

        JPanel buttons = new JPanel(new GridLayout(4, 4, 2, 2));
        ui.add(buttons, BorderLayout.CENTER);
        String[] keyValues = {
            "7", "8", "9", "/",
            "4", "5", "6", "*",
            "1", "2", "3", "-",
            "0", ".", "C", "+"
        };

        for (String keyValue : keyValues) {
            addButton(buttons, keyValue);
        }

        JButton equals = new JButton("=");
        configureButton(equals);
        ui.add(equals, BorderLayout.LINE_END);

        ui.setBorder(new EmptyBorder(5, 5, 5, 5));
    }

    public JComponent getUI() {
        return ui;
    }

    public void addButton(Container c, String text) {
        JButton b = new JButton(text);
        configureButton(b);
        c.add(b);
    }

    public void configureButton(JButton b) {
        Font f = b.getFont();
        b.setFont(f.deriveFont(f.getSize() * 1.5f));
        b.addActionListener(this);
        b.addKeyListener(this);
        controls.add(b);
    }

    public void calculateResult() {
        try {
            Object result = engine.eval(io.getText());
            if (result == null) {
                io.setText("Output was 'null'");
            } else {
                io.setText(result.toString());
            }
        } catch (ScriptException se) {
            io.setText(se.getMessage());
        }
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        String command = ae.getActionCommand();
        switch (command) {
            case "C":
                io.setText("");
                break;
            case "=":
                calculateResult();
                break;
            default:
                io.setText(io.getText() + command);
                break;
        }
    }

    private JButton getButton(String text) {
        for (JButton button : controls) {
            String s = button.getText();
            if (text.endsWith(s)
                    || (s.equals("=")
                    && (text.equals("Equals") || text.equals("Enter")))) {

                return button;
            }
        }
        return null;
    }

    /* START - Because I hate mice. */
    @Override
    public void keyPressed(KeyEvent ke) { }

    @Override
    public void keyReleased(KeyEvent ke) {
        String s = KeyEvent.getKeyText(ke.getKeyCode());
        JButton b = getButton(s);
        if (b != null) {
            b.requestFocusInWindow();
            b.doClick();
        }
    }

    @Override
    public void keyTyped(KeyEvent ke) { }
    /* END - Because I hate mice. */

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            ScriptEngineCalculator sc = new ScriptEngineCalculator();
            JFrame f = new JFrame("Calculet");
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setContentPane(sc.getUI());
            f.pack();
            f.setMinimumSize(f.getSize());
            f.setLocationByPlatform(true);
            f.setVisible(true);
        });
    }
}

1
那段代码当然能正常工作。但你觉得这是个糟糕的面向对象的代码吗?没关系,我相信你比我更有经验。 - Mohayemin
5
“但是你不认为那是一个糟糕的OO代码吗?”这是一个SSCCE。 SSCCE被允许省略很多东西,包括“面向对象设计”的一点点。 这个想法是从SSCCE中获取一些想法,然后将它们调整到您的设计中。 或者换句话说,“电池不包括在内”。;) - Andrew Thompson
1
@Andrew:我明白了。看到有经验的人写出那样的代码,我感到很惊讶。我在StackOverflow上很新,所以不了解很多东西。我正在学习 :) - Mohayemin

4

您可以检查源代码是否为按钮(实际上并非必要,因为您应该知道它仅从按钮中调用),然后将其强制转换为按钮并使用 .getText() 方法。

String sourceText;
if (ae.getSource() instanceof Button) {
sourceText = ((Button)ae.getSource()).getText();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接