Frage

I have a JFormattedTextField component with an Integer value that is updated 3 times in a second when it doesn't have focus.

For updating the value I use Swing Timer.

I want to make it possible for user to edit its value(to update some value in the model) but I know that the value of a JFormattedTextField isn't updated every time it loses the focus. so it's not wise to change the model attributes in the lostFocus event and on the other hand when it loses the focus its value can be changed by the updater module which makes the situation more difficult.

It is clear that I can't use the propertyListener neither, because the value is updated 3 times in a second!

Now I wonder how I will be able to update the variable on place profiting JFormattedTextField capabilities and let updater update my JFormattedTextField when it doesn't have focus! Is it possible or I must use an inputDialog instead? How?

For example in the following code when I change the field value to 200 in the GUI and then click on the JFrame to make it lose focus the value printed in the console isn't 200. It's a great random value that was previously in the field.

public class SwingTimerFormattedTextFieldTester {

    public static void main(String... args){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(0, 0, 300, 200);
        final JFormattedTextField field = new JFormattedTextField(new Long(100));
        field.setColumns(20);
        frame.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                frame.requestFocus();
                e.consume();
            }


        });

        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(field);
        frame.setVisible(true);

        Timer timer = new Timer(330, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if(!field.hasFocus()){
                    field.setValue(ThreadLocalRandom.current().nextLong());
                }
            }
        });
        timer.start();

        field.addFocusListener(new FocusListener() {

            @Override
            public void focusGained(FocusEvent e) {
                field.setBackground(Color.CYAN);
            }

            @Override
            public void focusLost(FocusEvent e) {
                field.setBackground(Color.WHITE);
                System.out.println(String.valueOf((Long)field.getValue()));
            }
        });

        frame.requestFocus();
    }

}
War es hilfreich?

Lösung

What if you commit the edit to the JFormattedTextField on focus lost?

 @Override
 public void focusLost(FocusEvent e) {
    try {
       if (field.isEditValid()) {
          field.commitEdit();
       }
    } catch (ParseException e1) {
       e1.printStackTrace();
    }
    field.setBackground(Color.WHITE);
    System.out.println(String.valueOf((Long) field.getValue()));
 }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top