Following the Question Synchronize JTextField values by property change listener
I have tried to modify the example from the answer using document listener. What I wanted to modify was to synchronize only integers. For example, if I put '2' in field1 then it would multiply by '5' so that the value would be '10' in the field2. However, I have followed various methods but I am having some errors such as:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""
Moreover, when I delete all values from field1, the last synchronized field2 value remains whereas field2 also supposed to be null as field1. I am not sure which part I have made mistake. Here is my code sample for the UpdateLabel Method:
private void updateLabel(DocumentEvent e) {
java.awt.EventQueue.invokeLater(new Runnable() {
String text = field.getText();
String text1 = field1.getText();
@Override
public void run() {
if(text == null && text1 != null){field1.setText(null);
}else
if(text.contains("-") ||
text.contains(".") ||
text.matches(".*[a-zA-Z].*")||
text.matches(".*\\p{Punct}.*")){
{JOptionPane.showMessageDialog(frame = new JFrame(),
"Please put appropriate int value from 0-9",
"Inane error",
JOptionPane.ERROR_MESSAGE);
field.setText(null);
field1.setText(null);
}
}else{
int p;
p = Integer.parseInt(text);
int i = (p*5);
String s = String.valueOf(i);
field1.setText(s);
}
}
});
}
I also want to use the '.' with integers but when I removetext.contains(".")
it still shows JOptionPane
error message.
You're getting NumberFormatException
because nothing can't be converted to a number, when you clear the text from field
so you need to check if the field is empty.
if (!text.isEmpty()) {
int p = Integer.parseInt(text);
int i = (p * 5);
String s = String.valueOf(i);
field1.setText(s);
} else {
field1.setText(null);
}
Also as I noted in the comments, with links, just use a DocumentFilter
allow only numbers.
Here is a refactor of your code. It works without the NumberFormatException
. I added the DocumentFilter
import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
public class TestLabelMirror {
private JPanel mainPanel = new JPanel();
private JTextField field = new JTextField(20);
private JTextField field1 = new JTextField(20);
private JFrame frame;
public TestLabelMirror() {
field.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
updateLabel(e);
}
@Override
public void insertUpdate(DocumentEvent e) {
updateLabel(e);
}
@Override
public void removeUpdate(DocumentEvent e) {
updateLabel(e);
}
private void updateLabel(DocumentEvent e) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
String text = field.getText();
String text1 = field1.getText();
if (!text.isEmpty()) {
int p = Integer.parseInt(text);
int i = (p * 5);
String s = String.valueOf(i);
field1.setText(s);
} else {
field1.setText(null);
}
}
});
}
});
((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
throws BadLocationException {
fb.insertString(off, str.replaceAll("\\D++", ""), attr); // remove non-digits
}
@Override
public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
throws BadLocationException {
fb.replace(off, len, str.replaceAll("\\D++", ""), attr); // remove non-digits
}
});
mainPanel.setLayout(new GridLayout(1, 0, 10, 0));
mainPanel.add(field);
mainPanel.add(field1);
}
public JComponent getComponent() {
return mainPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("TextLabelMirror");
frame.getContentPane().add(new TestLabelMirror().getComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowUI();
}
});
}
}