How to Find a Button Source in Awt (Calculator Homework)

Trying to find a way to incorporate the parse Int into my calculator

Copying the whole code into the question is a bit too much, but let me suggest you a hint as more or less pseudocode:

String numToConvert = textField.getText();
try {
int num = new Integer(numToConvert);
//sum up or ...
} catch (Exception e) { //numToConvertIsNotAnInteger
//-> must be an operator
}

Where do I implement my functions?

Use the MVC pattern and put the logic code that would go into the actionPerformed(...) method (Or any logic code for that matter) into a corresponding method in the controller class.


The MVC pattern consists of three classes, the Model, View, and Control, that work together to make a GUI.

A brief summary of the MVC pattern, taken originally from this answer, but slightly modified:

  1. You’re the user — you interact with the view. The controller takes your actions and interprets them. If you click on a button, it’s the controller’s job to figure out what that means and how the model should be manipulated based on that action.
  2. The controller asks the model to change its state. When the controller receives an action from the view, it may need to tell the view to change as a result. For example, the controller could enable or disable certain buttons or menu items in the interface.
  3. The model notifies the view when its state has changed. When something changes in the model, based either on some action you took (like clicking a button) or some other internal change (like the next song in the playlist has started), the model notifies the view that its state has changed.
  4. The controller may also ask the view to change.
  5. The view asks the model for its state. The view gets the state it displays directly from the model. For instance, when the model notifies the view that a new song has started playing, the view requests the song name from the model and displays it. The view might also ask the model for state as the result of the controller requesting some change in the view.

A more detailed and in-depth explanation of the MVC pattern can be found in the link above, on Oracle's website, and with a simple Google search.


I choose to use the observer pattern for my model-view interaction.

A example of a program using the MVC structure:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

class Test {

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
final Model model = new Model();
final Control control = new Control(model);
final View view = new View(model, control);

final JFrame frame = new JFrame("MVC Example");
frame.getContentPane().add(view);
frame.pack();
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}

});
}

static class Model extends Observable {

private int number;

void setNumber(int newValue) {
number = newValue;
setChanged();
notifyObservers(number);
}

int getNumber() {
return number;
}

}

static class View extends JPanel {

View(Model model, Control control) {
final JLabel label = new JLabel(Integer.toString(model.getNumber()));
final JButton button = new JButton("Click me!");
button.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
control.buttonPressed();
}

});

setLayout(new BorderLayout());
add(label);
add(button, BorderLayout.SOUTH);

model.addObserver(new Observer() {

@Override
public void update(Observable o, Object arg) {
label.setText(Integer.toString((int) arg));
}

});
}

}

static class Control {

private Model model;

Control(Model model) {
this.model = model;
}

void buttonPressed() {
model.setNumber(model.getNumber() + 1);
}

}

}

Notes on your code:

  • Take a look at arrays and the for loop to help you to simplify the declaration of your buttons.
  • Instead of setting your JFrames size, call pack() on your JFrame after you have added all your components to fit your JFrame to its children's size.
  • Don't extend JFrame, instead create an instance of one and make the necessary modifications.
  • Run your code on the EDT (Event Dispatch Thread) to avoid "freezing" in your GUI. For more information take a look at The Java™ Tutorials - Concurrency in Swing
  • Next time you post consider posting, for better help sooner, post a MCVE.

Java calculator not allowing for single inputs

On line 210 you have:

txtDisplay.setText(btnOneTxt);

What that does is set the entire contents of the JTextField txtDisplay to btnOneTxt. So each time you click the button, you replace what's already in txtDisplay with btnOneTxt.

What you want to do is append to what is already in the text field with the button text, like this

txtDisplay.setText(txtDisplay.getText() + btnOneText);

Just as a side note however, your GUI code is really messy. I'm not sure how much you wrote or how much was given to you to prompt the assignment, but you might consider storing the buttons in an array so you can execute the same function on all of them with a loop.

Trouble determining how to make my calculator calculate properly

When you click on the +, you're calling this:

    knopOptel.addActionListener((ActionEvent e) ->
{
String invoer = invoerVak.getText();
int invoerGetal = Integer.parseInt(invoer);
rekenmachine.addition(invoerGetal);
invoerVak.setText("");
});

But when you click on +, you're not doing the calculation yet! What you should be doing is:

  • The user type a number
  • The user click on + (for example)
  • In your ActionListener, you read the number on the screen, you store it in getal, you clear the screen, and you set your boolean optel to true
  • The user types another number
  • The user click on equal
  • In your equal Listener, you read the number you read the number on the screen, and depending on the flag (optel in the example), you calculate the result
  • you display the result

So indeed, the calculation is done when you press equal.

A small code example:

knopOptel.addActionListener((ActionEvent e) ->
{
int invoerGetal = Integer.parseInt(invoerVak.getText()); // get the number
calculate(invoerGetal); //sets totalNumber to what it should be by looking at the flags
invoerVak.setText(totalNumber); // we write the temporary result
additionFlag = true; // next number must be added
});

And your calculate function should just be something like:

private void calculate(int aInvoerGetal) {
if (addition)
totalNumber += aInvoerGetal;
else if (substract)
totalNumber -= aInvoerGetal;
else if (divide)
totalNumber /= aInvoerGetal;
else if (multiply)
totalNumber *= aInvoerGetal;

resetFlags();
}

TO GO FURTHER:

Now, if you want to support multiple caculations (5+5+5+3), it's easy. When you click on +, -, *, /, you first call the equalActionListener.

This way, you get this kind of sequence:

  1. 5, + // ==> equal called ==> 5 (because the flags are all false) ==> flag + to true

  2. 10, + // ==> equal called ==> 15 because 5 in memory and + flag was on. + flag goes off, then on again (because you pressed + again)

  3. 4, = // ==> equal called ==> 19

Java Simple Calculator

Get the calculation as a string and use ScriptEngine:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
t.setText(engine.eval(calculation_String));


Related Topics



Leave a reply



Submit