Value Change Listener to JTextField

前端 未结 12 1952
情歌与酒
情歌与酒 2020-11-22 04:16

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

相关标签:
12条回答
  • 2020-11-22 04:33

    DocumentFilter ? It gives you the ability to manipulate.

    [ http://www.java2s.com/Tutorial/Java/0240__Swing/FormatJTextFieldstexttouppercase.htm ]

    Sorry. J am using Jython (Python in Java) - but easy to understand

    # python style
    # upper chars [ text.upper() ]
    
    class myComboBoxEditorDocumentFilter( DocumentFilter ):
    def __init__(self,jtext):
        self._jtext = jtext
    
    def insertString(self,FilterBypass_fb, offset, text, AttributeSet_attrs):
        txt = self._jtext.getText()
        print('DocumentFilter-insertString:',offset,text,'old:',txt)
        FilterBypass_fb.insertString(offset, text.upper(), AttributeSet_attrs)
    
    def replace(self,FilterBypass_fb, offset, length, text, AttributeSet_attrs):
        txt = self._jtext.getText()
        print('DocumentFilter-replace:',offset, length, text,'old:',txt)
        FilterBypass_fb.replace(offset, length, text.upper(), AttributeSet_attrs)
    
    def remove(self,FilterBypass_fb, offset, length):
        txt = self._jtext.getText()
        print('DocumentFilter-remove:',offset, length, 'old:',txt)
        FilterBypass_fb.remove(offset, length)
    
    // (java style ~example for ComboBox-jTextField)
    cb = new ComboBox();
    cb.setEditable( true );
    cbEditor = cb.getEditor();
    cbEditorComp = cbEditor.getEditorComponent();
    cbEditorComp.getDocument().setDocumentFilter(new myComboBoxEditorDocumentFilter(cbEditorComp));
    
    0 讨论(0)
  • 2020-11-22 04:34

    I am brand new to WindowBuilder, and, in fact, just getting back into Java after a few years, but I implemented "something", then thought I'd look it up and came across this thread.

    I'm in the middle of testing this, so, based on being new to all this, I'm sure I must be missing something.

    Here's what I did, where "runTxt" is a textbox and "runName" is a data member of the class:

    public void focusGained(FocusEvent e) {
        if (e.getSource() == runTxt) {
            System.out.println("runTxt got focus");
            runTxt.selectAll();
        }
    }
    
    public void focusLost(FocusEvent e) {
        if (e.getSource() == runTxt) {
            System.out.println("runTxt lost focus");
            if(!runTxt.getText().equals(runName))runName= runTxt.getText();
            System.out.println("runText.getText()= " + runTxt.getText() + "; runName= " + runName);
        }
    }
    

    Seems a lot simpler than what's here so far, and seems to be working, but, since I'm in the middle of writing this, I'd appreciate hearing of any overlooked gotchas. Is it an issue that the user could enter & leave the textbox w/o making a change? I think all you've done is an unnecessary assignment.

    0 讨论(0)
  • 2020-11-22 04:39

    If we use runnable method SwingUtilities.invokeLater() while using Document listener application is getting stuck sometimes and taking time to update the result(As per my experiment). Instead of that we can also use KeyReleased event for text field change listener as mentioned here.

    usernameTextField.addKeyListener(new KeyAdapter() {
        public void keyReleased(KeyEvent e) {
            JTextField textField = (JTextField) e.getSource();
            String text = textField.getText();
            textField.setText(text.toUpperCase());
        }
    });
    
    0 讨论(0)
  • 2020-11-22 04:42

    Be aware that when the user modify the field, the DocumentListener can, sometime, receive two events. For instance if the user selects the whole field content, then press a key, you'll receive a removeUpdate (all the content is remove) and an insertUpdate. In your case, I don't think it is a problem but, generally speaking, it is. Unfortunately, it seems there's no way to track the content of the textField without subclassing JTextField. Here is the code of a class that provide a "text" property :

    package net.yapbam.gui.widget;
    
    import javax.swing.JTextField;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.PlainDocument;
    
    /** A JTextField with a property that maps its text.
     * <br>I've found no way to track efficiently the modifications of the text of a JTextField ... so I developed this widget.
     * <br>DocumentListeners are intended to do it, unfortunately, when a text is replace in a field, the listener receive two events:<ol>
     * <li>One when the replaced text is removed.</li>
     * <li>One when the replacing text is inserted</li>
     * </ul>
     * The first event is ... simply absolutely misleading, it corresponds to a value that the text never had.
     * <br>Anoter problem with DocumentListener is that you can't modify the text into it (it throws IllegalStateException).
     * <br><br>Another way was to use KeyListeners ... but some key events are throw a long time (probably the key auto-repeat interval)
     * after the key was released. And others events (for example a click on an OK button) may occurs before the listener is informed of the change.
     * <br><br>This widget guarantees that no "ghost" property change is thrown !
     * @author Jean-Marc Astesana
     * <BR>License : GPL v3
     */
    
    public class CoolJTextField extends JTextField {
        private static final long serialVersionUID = 1L;
    
        public static final String TEXT_PROPERTY = "text";
    
        public CoolJTextField() {
            this(0);
        }
    
        public CoolJTextField(int nbColumns) {
            super("", nbColumns);
            this.setDocument(new MyDocument());
        }
    
        @SuppressWarnings("serial")
        private class MyDocument extends PlainDocument {
            private boolean ignoreEvents = false;
    
            @Override
            public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                String oldValue = CoolJTextField.this.getText();
                this.ignoreEvents = true;
                super.replace(offset, length, text, attrs);
                this.ignoreEvents = false;
                String newValue = CoolJTextField.this.getText();
                if (!oldValue.equals(newValue)) CoolJTextField.this.firePropertyChange(TEXT_PROPERTY, oldValue, newValue);
            }
    
            @Override
            public void remove(int offs, int len) throws BadLocationException {
                String oldValue = CoolJTextField.this.getText();
                super.remove(offs, len);
                String newValue = CoolJTextField.this.getText();
                if (!ignoreEvents && !oldValue.equals(newValue)) CoolJTextField.this.firePropertyChange(TEXT_PROPERTY, oldValue, newValue);
            }
        }
    
    0 讨论(0)
  • 2020-11-22 04:44

    I know this relates to a really old problem, however, it caused me some problems too. As kleopatra responded in a comment above, I solved the problem with a JFormattedTextField. However, the solution requires a bit more work, but is neater.

    The JFormattedTextField doesn't by default trigger a property change after every text changes in the field. The default constructor of JFormattedTextField does not create a formatter.

    However, to do what the OP suggested, you need to use a formatter which will invoke the commitEdit() method after each valid edit of the field. The commitEdit() method is what triggers the property change from what I can see and without the formatter, this is triggered by default on a focus change or when the enter key is pressed.

    See http://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html#value for more details.

    Create a default formatter (DefaultFormatter) object to be passed to the JFormattedTextField either via its constructor or a setter method. One method of the default formatter is setCommitsOnValidEdit(boolean commit), which sets the formatter to trigger the commitEdit() method every time the text is changed. This can then be picked up using a PropertyChangeListener and the propertyChange() method.

    0 讨论(0)
  • 2020-11-22 04:44

    it was the update version of Codemwnci. his code is quite fine and works great except the error message. To avoid error you must change the condition statement.

      // 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 (textField.getText().length()>0){
           JOptionPane.showMessageDialog(null,
              "Error: Please enter number bigger than 0", "Error Massage",
              JOptionPane.ERROR_MESSAGE);
         }
      }
    });
    
    0 讨论(0)
提交回复
热议问题