Reputation: 11
Im building a basic calculator using jswing and I have two textfield, one for input #1 and for input #2. The question is, how can I continue putting my input so that when I finished entering my first input it should go to the next textfield for my second input? And also theres seems to be an error when operating the arithmetic formulation, the output displays the wrong answer or the total of two inputs.
import java.awt.event.*;
class Kalkuleytor implements ActionListener
{
JFrame f;
JTextField t1, t2, t3;
JLabel lbl1, lbl2, lbl3, lbl4;
JButton one,two,three,four,five,six,seven,eight,nine,zero,add,mltply,sbtrct,dvd,equal;
static double a=0,b=0,c=0,result=0;
static int operator=0;
Kalkuleytor()
{
f=new JFrame("Calculator");
t1=new JTextField();
t2=new JTextField();
t3=new JTextField();
lbl1=new JLabel("Number 1");
lbl2=new JLabel("Number 2");
lbl3=new JLabel("");
lbl4=new JLabel("Total");
one=new JButton("1");
two=new JButton("2");
three=new JButton("3");
four=new JButton("4");
five=new JButton("5");
six=new JButton("6");
seven=new JButton("7");
eight=new JButton("8");
nine=new JButton("9");
zero=new JButton("0");
dvd=new JButton("/");
mltply=new JButton("*");
sbtrct=new JButton("-");
add=new JButton("+");
equal=new JButton("=");
//setBounds and add of buttons
f.setLayout(null);
f.setVisible(true);
f.setSize(517,502);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
one.addActionListener(this);
//ActionListener for all button
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==one)
t1.setText("1");
if(e.getSource()==two)
t1.setText("2");
if(e.getSource()==three)
t1.setText("3");
if(e.getSource()==four)
t1.setText("4");
if(e.getSource()==five)
t1.setText("5");
if(e.getSource()==six)
t1.setText("6");
if(e.getSource()==seven)
t1.setText("7");
if(e.getSource()==eight)
t1.setText("8");
if(e.getSource()==nine)
t1.setText("9");
if(e.getSource()==zero)
t1.setText("0");
if(e.getSource()==add)
{
a=Double.parseDouble(t1.getText());
operator=1;
lbl3.setText("+");
}
if(e.getSource()==sbtrct)
{
a=Double.parseDouble(t1.getText());
operator=2;
lbl3.setText("-");
}
if(e.getSource()==mltply)
{
a=Double.parseDouble(t1.getText());
operator=3;
lbl3.setText("*");
}
if(e.getSource()==dvd)
{
a=Double.parseDouble(t1.getText());
operator=4;
lbl3.setText("/");
}
if(e.getSource()==equal)
{
c=Double.parseDouble(t1.getText());
switch(operator)
{
case 1: result=a+b;
break;
case 2: result=a-b;
break;
case 3: result=a*b;
break;
case 4: result=a/b;
break;
default: result=0;
}
t3.setText(""+result);
}
}
public static void main(String[]args)
{
new Kalkuleytor();
}
}
Upvotes: 0
Views: 1178
Reputation: 544
You have more than one issue in this code.
Textfields are for displaying so you can better use a separate variable of type String to register the input from the buttons 0-9 and concatenate them. Fill t1 of t2 depending on a boolean
Add the variables
String input = "";
boolean firstInput = true;
if(e.getSource()==one)
t1.setText("1");
will become
if(e.getSource()==one){
input += "1";
if (firstInput ) {
t1.setText(input);
}
else {
t2.setText(input);
}
}
On the operators change
if(e.getSource()==add) {
a=Double.parseDouble(t1.getText());
operator=1;
lbl3.setText("+");
}
if(e.getSource()==add) {
a=Double.parseDouble(input);
operator=1;
lbl3.setText("+");
firstInput = false;
input = "";
}
on the equal sign
if(e.getSource()==equal)
{
c=Double.parseDouble(t1.getText());
switch(operator)
{
case 1: result=a+b;
break;
case 2: result=a-b;
break;
case 3: result=a*b;
break;
case 4: result=a/b;
break;
default: result=0;
}
t3.setText(""+result);
}
}
to
if(e.getSource()==equal) {
b=Double.parseDouble(input);
switch(operator)
{
....
}
t3.setText(""+result);
firstInput = false;
input = "";
}
Upvotes: 0
Reputation: 54148
To give the focus to an input you may use requestFocusInWindow()
The wrong result may come from that you used the wrong variable, in the equal
if, you read the text into c
and use b
in the computations :
if (e.getSource() == equal) {
b = Double.parseDouble(t1.getText());
switch (operator) {
//...
Also you may simplify your code, you can easily refactor it:
use else if
when you can, like to get the number from the button, it can be one case only, don't try all, same for operators
if(e.getSource()==one)
t1.setText("1");
else if(e.getSource()==two)
t1.setText("2");
You may directly read the JButton text from it and use it, don't try all possibilities
Object source = e.getSource();
if (source instanceof JButton) {
JButton btn = (JButton) source;
String textStr = btn.getText();
if (textStr.matches("\\d")) {
t1.setText(textStr);
} else {
lbl3.setText(textStr);
a = Double.parseDouble(t1.getText());
operator = textStr;
}
}
You may also directly use a String
to store the operator, don't bother you to pass to an int
if (e.getSource() == equal) {
b = Double.parseDouble(t1.getText());
switch (operator) {
case "+":
result = a + b;
break;
case "-":
result = a - b;
break;
case "*":
result = a * b;
break;
case "/":
result = a / b;
break;
default:
result = 0;
}
t3.setText("" + result);
}
Using more specific features, like BiFunction
you could do :
Map<String, BiFunction<Double, Double, Double>> operators = new HashMap<>() {{
put("+", (d1, d2) -> d1 + d2);
put("-", (d1, d2) -> d1 - d2);
put("*", (d1, d2) -> d1 * d2);
put("/", (d1, d2) -> d1 / d2);
}};
And
} else { // For = button
b = Double.parseDouble(t1.getText());
result = operators.getOrDefault(operator, (d1, d2) -> 0.0).apply(a, b);
t3.setText("" + result);
}
Upvotes: 1
Reputation: 559
You need to use requestFocusInWindow() after you click on any operator (+,-,*,/,etc).
Upvotes: 1