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

2

9

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();
    }
}
Graehl answered 16/9, 2011 at 7:46 Comment(1)
which line/part of code creates a problem?Inclusive
P
19

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.

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);
        });
    }
}
Penzance answered 16/9, 2011 at 8:7 Comment(3)
That code works good of course. But dont you think thats a poor OO Code? Never mind, I am sure you are much more experienced than me.Ute
@Mohaimin "But dont you think thats a poor OO Code?" It is an SSCCE. SSCCEs are excused from many things, including an iota of 'OO design'. The idea is to pick up some ideas from the SSCCE, then adapt them into your design. Or to put that another way 'Batteries not included'. ;)Penzance
@Andrew: I understand. I was surprised to see that kind of code from an experienced person I am very new in StackOverflow so I am not aware of many things. I am learning :)Ute
O
4

You can check if your source is a Button (not actually nessesary since you should know it is only called from a button) and then type cast to a button and use .getText()

String sourceText;
if (ae.getSource() instanceof Button) {
sourceText = ((Button)ae.getSource()).getText();
}
One answered 16/9, 2011 at 8:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.