Value Change Listener to JTextField
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);
}
}
});
Change Listener for a JTextfield
Just add a listener to the textfield so that it tracks when the text changes
textfieldName.getDocument().addDocumentListener(new DocumentListener() {
// implement the methods
});
how add a listener for jtexfield when it changing?
The appropriate listener in Java's swing to track changes in the text content of a JTextField is a DocumentListener, that you have to add to the document of the JTextField:
myTextField.getDocument().addDocumentListener(new DocumentListener() {
// implement the methods
});
Value Change Listener to JTextField
jTsearch.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
//whatever you want
}
public void removeUpdate(DocumentEvent e) {
//whatever you want
}
public void insertUpdate(DocumentEvent e) {
//whatever you want
}
}
});
Listeners for JTextField text change
For the first one, you need a FocusListener. For the second one, you need to add a DocumentListener to the document of the text field.
Action listener for a JTextField to change value in another textfield
I'm assuming that you don't understand that ActionListener
will only be notified when the user presses the Enter key...
That would be the easiest solution, if, however, you want to monitor changes to a text component, you should use a DocumentListener
See How to Use Text Fields, How to Write an Action Listeners and Listening for Changes on a Document for more details
This, however, raises some issues. When do you assume the user has stopped typing?
There is a significant difference between 100
and 1
and 0
and 0
, so what we need is someway to defer the event notification to some time in the future, where we can "assume" that the user has stopped typing (or at least long enough for us to grab a reasonable value)
public class DeferredDocumentChangedListener implements DocumentListener {
private Timer timer;
private List<ChangeListener> listeners;
public DeferredDocumentChangedListener() {
listeners = new ArrayList<>(25);
timer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fireStateChanged();
}
});
timer.setRepeats(false);
}
public void addChangeListener(ChangeListener listener) {
listeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
listeners.remove(listener);
}
protected void fireStateChanged() {
if (!listeners.isEmpty()) {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
}
@Override
public void insertUpdate(DocumentEvent e) {
timer.restart();
}
@Override
public void removeUpdate(DocumentEvent e) {
timer.restart();
}
@Override
public void changedUpdate(DocumentEvent e) {
timer.restart();
}
}
Okay, so, this is a little trick. This is a simple observable DocumentListener
, which provides event notification at some point in the future that the document has changed. In your case, you don't really care about the change, just that it has.
This sets up a non-repeating Swing Timer
with a short delay (250 milliseconds in the example) which if it's not reset for that period of time, will notify any registered ChangeListener
s. If, however, the Document
is modified within that time period, the Timer
is reset.
You may want to play around with the "time out" value ;)
Which you could then use something like...
JTextField number = new JTextField(5);
JTextField sum = new JTextField("0", 5);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(number, gbc);
add(sum, gbc);
DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener();
listener.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int num1 = Integer.parseInt(number.getText());
int num2 = Integer.parseInt(sum.getText());
int result = num1 + num2;
sum.setText(Integer.toString(result));
number.selectAll();
}
});
number.getDocument().addDocumentListener(listener);
This, obviously doesn't provide any validation, so it could throw an exception if the text is not a number, but I'll leave that for you to figure out
You may also want to have a look at How to Use Spinners and How to Use Formatted Text Fields which provide post validation process which can help validate the user input.
You could also use a DocumentFilter
to further restrict what the user can enter, see Implementing a Document Filter and DocumentFilter Examples for more details
Value Change Listener for JavaFX's TextField
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);
});
Swing JTextField on text change
If you want to monitor for changes to one or more text fields, you should be using a DocumentListener
, this will also provide you notification's of when the user pastes text into the field or the field is changed programatically (via a call to setText
)
For example...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class Text {
public static void main(String[] args) {
new Text();
}
public Text() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JTextField field1 = new JTextField(10);
JTextField field2 = new JTextField(10);
JTextField field3 = new JTextField(10);
DocumentListener dl = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
updateFieldState();
}
@Override
public void removeUpdate(DocumentEvent e) {
updateFieldState();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateFieldState();
}
protected void updateFieldState() {
String text = field1.getText() + " " + field2.getText();
field3.setText(text);
}
};
field1.getDocument().addDocumentListener(dl);
field2.getDocument().addDocumentListener(dl);
field3.setEditable(false);
add(field1);
add(field2);
add(field3);
}
}
}
Now, it appear that you are trying to limit the character that can be typed into the field. You could use a JSpinner
or JFormattedTextField
, but these only provide post validation.
For real time validation, you should be using a DocumentFilter
, which will allow you to intercept what is entered into the field before it's applied to the underlying Document
.
See Implementing a DocumentFilter
and DocumentFilter
examples for more details
Swing JTextField text changed listener DocumentListener infinity loop
There are two approaches to properly solve this:
Fire a property change event only if actually something changed
There's no point in notifying if the property value is the same as before (not changed at all). Avoiding the unnecessary event will effectively break your loop:
public void setHost(String host) {
// check if property actually changed
if (Objects.equals(this.host, host) return;
String oldHost = this.host;
this.host = host;
this.firePropertyChange("Host", oldHost, this.host);
}
or (fancy compact form):
public void setHost(String host) {
if (!Objects.equals(this.host, host)) {
firePropertyChange("Host", this.host, this.host=host);
}
}
Do one-way synchronization to avoid cascades
Changing a propery in the model can change a property in the view can change a property in the model can change... - this can quickly run in circles.
To break these cascades, do a one-way synchronization:
while the model notifies the view about changes, ignore any cascading updates.
To do so, you need a flag on the controller (in your case, the view holding the microcontrollers a.k.a. Swing listeners):
MyView.java:
boolean updating;
@Override public void modelPropertyChange(final PropertyChangeEvent event)
{
if (updating) {
// cascading update, ignore
return;
}
updating=true;
try {
if(event.getPropertyName().equals("Username")) {
{
String username = (String) event.getNewValue();
this.nameField.setText(username);
}
...
}
finally {
updating=false;
}
}
The first approach is pretty straightforward (but can get complicated when dealing with complex objects and collections).
The second approach is easy and more forgiving by design - view always represents model (no changes missed), and cascading updates are blocked.
Let ActionListener listen for change in JTextField instead of only enter?
From an answer by @JRL
Use the underlying document:
myTextField.getDocument().addDocumentListener();
Related Topics
What Is the Equivalent of the C++ Pair≪L,R≫ in Java
Declaring Variables Inside or Outside of a Loop
How to Escape Text For Regular Expression in Java
How to Add Blank Page in Digitally Signed Pdf Using Java
Difference Between Declaring Variables Before or in Loop
How to Establish a Connection Pool in Jdbc
Something Seems Wrong With the Layout, Jbutton Showing Unexpected Behaviour At Resize of the Window
How to Turn a List of Lists into a List in Java 8
Get a List of All Threads Currently Running in Java
How to Loop Through a Hashmap in Jsp
What's Causing My Java.Net.Socketexception: Connection Reset
Sort on a String That May Contain a Number
System.Out.Println and System.Err.Println Out of Order
Should Java 8 Getters Return Optional Type
What Causes Javac to Issue the "Uses Unchecked or Unsafe Operations" Warning