简体   繁体   中英

synchronize jtextfield value into only integer value using document listener

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 remove text.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();
            }
        });
    }
}
int p=0;
try {
    p = Integer.parseInt(text);
}
catch (NumberFormatException ex) {
    //define here which number should be shown when input is incorrect. e.g. p=0;
}

You can wrap the value parsing and provide proper output for the case when source value can't be parsed correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM