Asked  7 Months ago    Answers:  5   Viewed   240 times

I want the message box to appear immediately after the user changes the value in the textfield. Currently, I need to hit the enter key to get the message box to pop out. Is there anything wrong with my code?

textField.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {

        if (Integer.parseInt(textField.getText())<=0){
            JOptionPane.showMessageDialog(null,
                    "Error: Please enter number bigger than 0", "Error Message",
                    JOptionPane.ERROR_MESSAGE);
        }       
    }
}

Any help would be appreciated!

 Answers

74

Add a listener to the underlying Document, which is automatically created for you.

// Listen for changes in the text
textField.getDocument().addDocumentListener(new DocumentListener() {
  public void changedUpdate(DocumentEvent e) {
    warn();
  }
  public void removeUpdate(DocumentEvent e) {
    warn();
  }
  public void insertUpdate(DocumentEvent e) {
    warn();
  }

  public void warn() {
     if (Integer.parseInt(textField.getText())<=0){
       JOptionPane.showMessageDialog(null,
          "Error: Please enter number bigger than 0", "Error Message",
          JOptionPane.ERROR_MESSAGE);
     }
  }
});
Tuesday, June 1, 2021
 
ShadowZzz
answered 7 Months ago
13

I'll make this an answer: I wouldn't use a DocumentListener for this purpose as it seems to me the wrong tool for the job. For one, it is continually listening and updating the results while the user is still entering data, data that is as yet incomplete, into the JTextField. Much better would be to use an ActionListener added to a JButton or to your JTextFields.

I suppose you could use a FocusListener, but even that concerns me since it is quite low-level.

Also: consider using an InputVerifier to validate your input.

Also: consider displaying your tabular data in a JTable where the 1st and 2nd columns are editable but the others are not.

Edit
I'm not sure if this is kosher, but it could work if you do your calculation from within the verifier. For example, updated for generality:

import javax.swing.*;

/**
* @see http://stackoverflow.com/a/11818183/522444
*/
public class VerifierEg {

    private static final String ZERO = "0.0";
    private JTextField field1 = new JTextField(ZERO, 5);
    private JTextField field2 = new JTextField(ZERO, 5);
    private JTextField resultField = new JTextField(ZERO, 10);

    private void createAndShowGui() {
        resultField.setEditable(false);
        resultField.setFocusable(false);

        JPanel mainPanel = new JPanel();
        final JTextField[] fields = {field1, field2};

        mainPanel.add(field1);
        mainPanel.add(new JLabel(" x "));
        mainPanel.add(field2);
        mainPanel.add(new JLabel(" = "));
        mainPanel.add(resultField);

        for (JTextField field : fields) {
            field.setInputVerifier(new MyInputVerifier(field));
        }

        JFrame frame = new JFrame("VerifierEg");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void calcProduct() {
        double d1 = Double.parseDouble(field1.getText());
        double d2 = Double.parseDouble(field2.getText());
        double prod = d1 * d2;
        resultField.setText(String.valueOf(prod));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                VerifierEg eg = new VerifierEg();
                eg.createAndShowGui();
            }
        });
    }

    /**
    * @see http://stackoverflow.com/a/11818946/230513
    */
    private class MyInputVerifier extends InputVerifier {

        private JTextField field;
        private double value;

        public MyInputVerifier(JTextField field) {
            this.field = field;
        }

        @Override
        public boolean shouldYieldFocus(JComponent input) {
            if (verify(input)) {
                field.setText(String.valueOf(value));
                calcProduct();
                return true;
            } else {
                field.setText(ZERO);
                field.selectAll();
                return false;
            }

        }

        @Override
        public boolean verify(JComponent input) {
            try {
                value = Double.parseDouble(field.getText());
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    }
}
Wednesday, June 9, 2021
 
keisar
answered 6 Months ago
42

Add a listener to the TextField's textProperty:

TextField textField = new TextField();
textField.textProperty().addListener((observable, oldValue, newValue) -> {
    System.out.println("textfield changed from " + oldValue + " to " + newValue);
});
Wednesday, June 9, 2021
 
DaveRandom
answered 6 Months ago
80

Just add a listener to the textfield so that it tracks when the text changes

textfieldName.getDocument().addDocumentListener(new DocumentListener() {
    // implement the methods
});
Friday, August 27, 2021
 
Brendan
answered 3 Months ago
51

DocumentListeners do not permit the modification of the underlying document of the JTextComponent. You are looking for a DocumentFilter.

Example

Monday, November 22, 2021
 
ClmentM
answered 1 Week ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share