Search code examples
javaswinguser-interfacejformattedtextfield

JFormattedTextField deletes user input


I have the following code:

public test() {
    setLayout(new FlowLayout());
    JFormattedTextField price = new JFormattedTextField(new DecimalFormat("#,##0.00 \u00A4"));
    price.setValue(new Float(105.00));
    add(price);
    add(new JButton("Ok"));

    pack();
    setVisible(true);

}

If I enter a number now, for example '20'. The textfield enters '105.00' again. Why it doesn't accept my entry and always goes back to the default value?


Solution

  • there are three ways starting with easiest, ending with useless, maybe nonsense in comparing with points 1st and 2nd.

    • use NumberFormat.getCurrencyInstance(); or NumberFormat.getCurrencyInstance(Locale); for Currency symbol, then this value is valid for concrete JTextField / JFormattedTextField / JSpinner / XxxCellRenderer / XxxCellEditor,

    code

    import java.awt.GridLayout;
    import java.math.RoundingMode;
    import java.text.NumberFormat;
    import javax.swing.JFormattedTextField;
    import javax.swing.JFrame;
    import javax.swing.text.NumberFormatter;
    
    public class MaskFormatterTest {
    
        public static void main(String[] args) throws Exception {
            //NumberFormat format = NumberFormat.getNumberInstance();
            NumberFormat format = NumberFormat.getCurrencyInstance();
            format.setMaximumFractionDigits(2);
            format.setMinimumFractionDigits(2);
            format.setParseIntegerOnly(true);
            format.setRoundingMode(RoundingMode.HALF_UP);
    
            NumberFormatter formatter = new NumberFormatter(format);
            formatter.setMaximum(1000.0);
            formatter.setMinimum(0.0);
            formatter.setAllowsInvalid(false);
            formatter.setOverwriteMode(false);
    
            JFormattedTextField tf = new JFormattedTextField(formatter);
            tf.setColumns(10);
            tf.setValue(123456789.99);
            JFormattedTextField tf1 = new JFormattedTextField(formatter);
            tf1.setValue(1234567890.99);
            JFormattedTextField tf2 = new JFormattedTextField(formatter);
            tf2.setValue(1111.1111);
            JFormattedTextField tf3 = new JFormattedTextField(formatter);
            tf3.setValue(-1111.1111);
            JFormattedTextField tf4 = new JFormattedTextField(formatter);
            tf4.setValue(-56);
    
            JFrame frame = new JFrame("Test");
            frame.setLayout(new GridLayout(5, 0));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(tf);
            frame.add(tf1);
            frame.add(tf2);
            frame.add(tf3);
            frame.add(tf4);
            frame.pack();
            frame.setVisible(true);
        }
    }
    

    .

    • apply own NavigationFilter, fixed possition could be on the start or ending for possition (Bias) in JTextField / JFormattedTextField / JSpinner / XxxCellRenderer / XxxCellEditor,

    code

    //@see & read http://stackoverflow.com/questions/7421337/limited-selection-in-a-jtextfield-jtextcomponent
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.text.*;
    
    public class NavigationFilterPrefixWithBackspace extends NavigationFilter {
    
        private int prefixLength;
        private Action deletePrevious;
    
        public NavigationFilterPrefixWithBackspace(int prefixLength, JTextComponent component) {
            this.prefixLength = prefixLength;
            deletePrevious = component.getActionMap().get("delete-previous");
            component.getActionMap().put("delete-previous", new BackspaceAction());
            component.setCaretPosition(prefixLength);
        }
    
        @Override
        public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {
            fb.setDot(Math.max(dot, prefixLength), bias);
        }
    
        @Override
        public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {
            fb.moveDot(Math.max(dot, prefixLength), bias);
        }
    
        class BackspaceAction extends AbstractAction {
    
            private static final long serialVersionUID = 1L;
    
            public void actionPerformed(ActionEvent e) {
                JTextComponent component = (JTextComponent) e.getSource();
                if (component.getCaretPosition() > prefixLength) {
                    deletePrevious.actionPerformed(null);
                }
            }
        }
    
        public static void main(String args[]) throws Exception {
            JTextField textField = new JTextField("Prefix_", 20);
            textField.setNavigationFilter(new NavigationFilterPrefixWithBackspace(7, textField));
            JFrame frame = new JFrame("Navigation Filter Example");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(textField);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    .

    • create own InputMask with InputVerifier, workaroung could / couldn't be different for (each of) JTextField / JFormattedTextField / JSpinner / XxxCellRenderer / XxxCellEditor,