How to find a button source in AWT (calculator homework)

awt, java

Solution

I would tend to have each button for the numbers, as well as each button for operands, add text to a text field that is the 'Input/Output'.

Also have a button `=` (equals). When the `=` button is activated, call the `ScriptEngine` to evaluate the content of the I/O text field and write the result back to it.

E.G.

=

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

Problem

We were asked to make a simple GUI calculator, I used getSource() to detect the buttons, cause that's what they taught us. It works by typing the 1st and 2nd value then choosing the operation, it worked. But I made a mistake, because what they want us to do is that the numbers should also be buttons, just like a real calculator. so how do i get the value of each button using getSource()? like when I press button 1 and 2 is equal to 3. heres what ive done ``` 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(); } } ```

Original source