Vince
Vince

Reputation: 15146

JTextField not clearing after setText("")

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

Answers (1)

MadProgrammer
MadProgrammer

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 Strings contents can't be changed, it can simply be reassigned...

Upvotes: 3

Related Questions