Search code examples
javaswingjoptionpanejformattedtextfield

JFormattedTextField returns default value only


I put a JFormattedTextField (instantiated with a NumberFormatter and given an initial random value) in a panel and that panel goes in a JOptionPane which gets displayed. When then I type a different random value in that JFormattedTextField and click OK, the JFormattedTextField returns the original value, not the one just typed in?! Minimal code example below. Hope you can help.

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.text.NumberFormatter;
import java.awt.*;

public class Weg {
    public static void main(String[] args) {
        final NumberFormatter numberFormatter = new NumberFormatter();
        numberFormatter.setMinimum(0);
        numberFormatter.setMaximum(Double.POSITIVE_INFINITY);

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(1, 2));

        panel.add(new JLabel("Enter positive value:"));
        JFormattedTextField textField = new JFormattedTextField(numberFormatter);
        textField.setPreferredSize(new Dimension(70, 1));
        textField.setValue(999.1); //Random initial value
        panel.add(textField);

        panel.setPreferredSize(new Dimension(250, 35));
        int result = JOptionPane.showConfirmDialog(null, panel, "Enter a value", JOptionPane.OK_CANCEL_OPTION);
        if (result == JOptionPane.OK_OPTION) {
            double val = (double) textField.getValue();
            System.out.println("Value entered = " + val); //Whatever you enter, the old 999.1 is returned here???
        }
    }
}

Solution

  • I use the code you posted with your question.

    When tested as is I see the problem you describe. That is I:

    1. deleted the first 9
    2. tab
    3. click Ok

    The result:

    1. 999.1 is still displayed in the formatted text field
    2. Value entered = 999.1 is displayed on the console.

    I then make the following change:

    //numberFormatter.setMinimum(0);
    //numberFormatter.setMaximum(Double.POSITIVE_INFINITY);
    

    and repeat the 3 steps above with the following result:

    1. 99.1 is displayed in the formatted text field
    2. Value entered = 99.1 is displayed on the console.

    So it works as expected.

    Next I try:

    numberFormatter.setMinimum(0);
    //numberFormatter.setMaximum(Double.POSITIVE_INFINITY);
    

    and repeat the 3 steps with the result:

    1. 99 is displayed in the formatted text field
    2. get Exception: class java.lang.Integer cannot be cast to class java.lang.Double

    So I realize the minimum value is being created as an Integer, not a Double so I try:

    numberFormatter.setMinimum( Double.valueOf(0) );
    //numberFormatter.setMaximum(Double.POSITIVE_INFINITY);
    

    with the result:

    1. 99.1 is displayed in the formatted text field
    2. Value entered = 99.1 is displayed on the console.

    So it works as expected.

    Finally I try:

    numberFormatter.setMinimum( Double.valueOf(10) );
    //numberFormatter.setMaximum(Double.POSITIVE_INFINITY);
    

    and delete the first two digits so only "9.1" is displayed, with the result:

    1. 999.1 is displayed in the formatted text field
    2. Value entered = 999.1 is displayed on the console.

    The the minimum value was respected and the code works as expected.

    I don't know why you would try to set the max value, since that is obviously the default.

    This is how you do basic debugging one step at a time. The point is to first isolate the problem by making a single change at a time.