JFormattedTextField issues
Asked Answered
G

1

8

enter image description here enter image description here

1) how can I set Cursor to 0 possition without using Caret or Focus wrapped into invokeLater() (confortly can be solved by using @camickr Formatted Text Field Tips), is there somebody who knows another way

enter image description here enter image description here

2) How to reset Formatter sometimes (by raising Focus by TAB from keyboard), reset doesn't works and on focusLost (empty field) Formatter returns/reincarnated chars or String back (last know before setText("");),

Note: know code or following code is only this way, about how to reset Formatter from OTN, but their terrible search rulles ...., only code (question or answer by Jeanette???)

import java.awt.event.*;
import java.beans.*;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.Document;

public class FormattedNull {

    private JFormattedTextField field;
    private JButton focusButton;

    private JComponent createContent() {
        JComponent content = new JPanel();
        field = new JFormattedTextField(new Integer(55));
        field.setColumns(20);
        field.addPropertyChangeListener(getPropertyChangeListener());
        field.getDocument().addDocumentListener(getDocumentListener());
        content.add(field);
        focusButton = new JButton("just something focusable");
        focusButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                field.setValue(0);
                field.requestFocusInWindow();
            }
        });
        content.add(focusButton);
        return content;
    }

    protected void maybeCommitEdit(Document document) {
        try {
            field.commitEdit();
        } catch (ParseException e) {
            // uncomment to map empty string to null
            if (field.getText().length() == 0) {
                field.setValue(null);
            }
        }
    }

    /*public void commitEdit() throws ParseException {
    if(allowsNull() && isBlank()) {
    setValue(null);
    }
    else {
    super.commitEdit();
    }
    }*/
    private PropertyChangeListener getPropertyChangeListener() {
        PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if ("value".equals(evt.getPropertyName())) {
                    matchValueChanged(evt.getNewValue());
                }
            }
        };
        return propertyChangeListener;
    }

    protected void matchValueChanged(Object value) {
        System.out.println("got new value: " + value);
    }

    private DocumentListener getDocumentListener() {
        DocumentListener documentListener = new DocumentListener() {

            @Override
            public void removeUpdate(DocumentEvent e) {
                maybeCommitEdit(e.getDocument());
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                maybeCommitEdit(e.getDocument());
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
            }
        };
        return documentListener;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new FormattedNull().createContent());
                frame.setLocationRelativeTo(null);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

enter image description here

attached images are based on my sscce

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.text.MaskFormatter;

public class TestTest {

    private JFormattedTextField myFormattedField1 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
    private JFormattedTextField myFormattedField2 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
    private JFormattedTextField myFormattedField3 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
    private JFormattedTextField myFormattedField4 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
    private JButton jb = new JButton("Reset to Default");
    private JFrame frame = new JFrame("Text Test");

    public TestTest() {
        myFormattedField1.setText("ABCDEFGHIJKL");
        myFormattedField2.setText("ABCDEFGHIJKL");
        myFormattedField3.setText("ABCDEFGHIJKL");
        myFormattedField4.setText("ABCDEFGHIJKL");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(150, 150);
        frame.setLayout(new GridLayout(5, 0));
        frame.add(jb);
        frame.add(myFormattedField1);
        frame.add(myFormattedField2);
        frame.add(myFormattedField3);
        frame.add(myFormattedField4);
        jb.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                myFormattedField1.setText("");
                myFormattedField2.setText("");
                myFormattedField3.setText("");
                myFormattedField4.setText("");
            }
        });
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        TestTest textTest = new TestTest();
    }

    protected MaskFormatter createFormatter(String s) {
        MaskFormatter formatter = null;
        try {
            formatter = new MaskFormatter(s);
        } catch (java.text.ParseException exc) {
            System.err.println("formatter is bad: " + exc.getMessage());
        }
        return formatter;
    }
}
Gasaway answered 11/9, 2011 at 14:21 Comment(1)
1) why? 2) empty string is an invalid entry, so the field reverts to the mask itself (set a placeHolderChar to see, spaces are invisible :-)Gingery
P
8
  1. On Mac OS, the default behavior of the UI delegate, com.apple.laf.AquaTextFieldF, is similar to CaretPositionListener:

    • Tab or Shift-Tab: place the caret at the beginning of the field.

    • Click: briefly place the caret at the beginning of the field and then move it to the click point.

    IMO, the CaretPositionListener does the latter much more smoothly.

  2. The default behavior of JFormattedTextField on focus lost is COMMIT_OR_REVERT. In the example below, Tab though the first, invalid field to see the effect. The formatter can neither commit nor revert to the invalid value, so it substitutes MASK.length() spaces. This value is valid, if a little obscure.

Addendum: I've updated the code below to allow changing the setFocusLostBehavior().

Code:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.MaskFormatter;

/** @see http://stackoverflow.com/questions/7378821 */
public class TrashTest {

    private static final String MASK = "########";
    private static final String DEFAULT = "01234567";
    private static final String BOGUS = "0123456";
    private JFormattedTextField jtf1 = createField();
    private JFormattedTextField jtf2 = createField();
    private JFormattedTextField jtf3 = createField();
    private JFormattedTextField jtf4 = createField();
    private JButton reset = new JButton("Reset to Default");
    private JComboBox combo = new JComboBox();
    private JFrame frame = new JFrame("Text Test");

    public TrashTest() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(150, 150);
        frame.setLayout(new GridLayout(0, 1));
        frame.add(reset);
        frame.add(jtf1);
        frame.add(jtf2);
        frame.add(jtf3);
        frame.add(jtf4);
        frame.add(combo);
        this.initFields();
        reset.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                initFields();
            }
        });
        for (Edit e : Edit.values()) {
            combo.addItem(e);
        }
        combo.setSelectedIndex(jtf1.getFocusLostBehavior());
        combo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Edit current = (Edit) combo.getSelectedItem();
                jtf1.setFocusLostBehavior(current.value);
            }
        });
        frame.pack();
        frame.setVisible(true);
    }

    private void initFields() {
        jtf1.setText(BOGUS);
        jtf2.setText(DEFAULT);
        jtf3.setText(DEFAULT);
        jtf4.setText(DEFAULT);
    }

    protected JFormattedTextField createField() {
        MaskFormatter formatter = null;
        try {
            formatter = new MaskFormatter(MASK);
        } catch (java.text.ParseException e) {
            e.printStackTrace(System.out);
        }
        JFormattedTextField jtf = new JFormattedTextField(formatter);
        return jtf;
    }

    enum Edit {

        COMMIT(JFormattedTextField.COMMIT),
        COMMIT_OR_REVERT(JFormattedTextField.COMMIT_OR_REVERT),
        REVERT(JFormattedTextField.REVERT),
        PERSIST(JFormattedTextField.PERSIST);
        private int value;

        private Edit(int n) {
            this.value = n;
        }

        public static Edit getEnum(int n) {
            for (Edit e : Edit.values()) {
                if (e.value == n) {
                    return e;
                }
            }
            return Edit.COMMIT_OR_REVERT;
        }
    }

    public static void main(String[] args) {
        TrashTest textTest = new TrashTest();
    }
}
Pogge answered 11/9, 2011 at 21:17 Comment(4)
This answer is rather empirical; I'd welcome any corrections or a better answer.Pogge
For reference, I've updated the code to allow selecting the focus-lost setting.Pogge
thanks I don't really understood how excelent ans correctly works your code, thanks for another lessonGasaway
Sorry it's not more constructive. The API says COMMIT_OR_REVERT is the default; I intended getEnum() as a check, but it's superfluous.Pogge

© 2022 - 2024 — McMap. All rights reserved.