Reputation: 15146
Before explaining, here's the code:
public class Calculator extends JFrame implements ActionListener {
private String[] ops = { "+", "-", "*", "/", "=" };
private JButton[] buttons = new JButton[16];
private JTextField field;
private int currentAnswer;
public Calculator() {
super("Calculator");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
addComponents();
pack();
setLocationRelativeTo(null);
}
private void addComponents() {
GridBagConstraints gbc = new GridBagConstraints();
field = new JTextField(10);
add(field, gbc);
gbc.gridy++;
add(buttons[0] = newButton("0"), gbc);
add(buttons[10] = newButton("+"), gbc);
}
@Override
public void actionPerformed(ActionEvent e) {
String text = field.getText();
/* Checks for operation chars */
for(int i = 0; i < ops.length; i++) {
if(text.endsWith(ops[i])) {
field.setText("");
System.out.println("called");
break;
}
}
/* Checks if number was pressed */
for (int i = 0; i <= 9; i++)
if (e.getSource() == buttons[i]) {
field.setText(text + buttons[i].getText());
return;
}
switch (e.getActionCommand()) {
case "+":
currentAnswer += Integer.parseInt(text);
field.setText(text + e.getActionCommand());
return;
}
}
public JButton newButton(String name) {
JButton newButton = new JButton(name);
newButton.addActionListener(this);
return newButton;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
Calculator calculator = new Calculator();
calculator.setVisible(true);
}
});
}
}
My goal is to check if my JTextField field
contains a math operator (which I have stored in a String array). If it does, "clear" the text field before moving on.
The problem is: My program is telling me the code has been executed ("called" prints out), yet my results show as if setText("")
was never called.
I did initialize all my components (and my frame) on the EDT. If you need to see the rest of the code, let me know (it's not much). A friend of mine sent me this, and I was trying to clean it up (iron out the bugs). I'm not sure if it's just a little thing I'm not seeing, but I know Swing has a lot of "rules", and it's really hard to keep up with it all /:
EDIT:
After pressing the "+" button, this is what happens when i press a number button afterwards
String text = field.getText();
System.out.println(text); // prints "0+" like expected (after pressing number)
/* Checks for operation chars */
for(int i = 0; i < ops.length; i++) {
if(text.endsWith(ops[i])) {
field.setText("");
System.out.println("called"); //gets printed
break;
}
}
System.out.println(text); //even when "called" prints, text is not ""
Why is it not clearing? :s
Upvotes: 0
Views: 1708
Reputation: 347184
There are a couple of problems...
First, your actionPerformed
method is doing exactly what you told it to
for (int i = 0; i < ops.length; i++) {
if (text.endsWith(ops[i])) {
field.setText("");
System.out.println("called");
break;
}
}
/* Checks if number was pressed */
for (int i = 0; i <= 9; i++) {
if (e.getSource() == buttons[i]) {
// Here, the field text is been rest to text + button.text...
field.setText(text + buttons[i].getText());
// And nothing will be executed after it...
return;
}
}
So, even if the field is cleared, it will always be set back to the existing value plus the value of the button's text...
What I "think" you want to do, is calculate the value of the field first, then process the button press...
Updated based on edits
// You assign the reference to the `String` maintained by the text field...
String text = field.getText();
System.out.println(text); // prints "0+" like expected (after pressing number)
/* Checks for operation chars */
for(int i = 0; i < ops.length; i++) {
if(text.endsWith(ops[i])) {
// You assign a NEW reference to the text field, this
// won't change the contents of text as they are different
// references...
field.setText("");
System.out.println("called"); //gets printed
break;
}
}
// text has not changed, this variable and the field contents are not
// magically linked
System.out.println(text); //even when "called" prints, text is not ""
Also, remember, String
in Java is nonmutable, meaning that once created, a String
s contents can't be changed, it can simply be reassigned...
Upvotes: 3