当 JFormattedTextField 为 clicked/focused 时,如何在其末尾设置插入符位置?

How to set caret position at the end of JFormattedTextField when it is clicked/focused?

我有 JFormattedTextField(s) 的框架。我的简化代码如下所示:

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100,100);
frame.setLayout(new GridLayout(2,2));

JFormattedTextField field1 = new JFormattedTextField(NumberFormat.getInstance());
field1.setValue(0.4);
frame.add(new JLabel("value A"));
frame.add(field1);

JFormattedTextField field2 = new JFormattedTextField(NumberFormat.getInstance());
field2.setValue(0.8);
frame.add(new JLabel("value B"));
frame.add(field2);

frame.setVisible(true);

生成:

目标

当我 click/focus 在任何 JFormattedTextField 上时,我希望它自动将插入符号放在末尾

问题

我在调用 frame.setVisible(true); 之前尝试使用以下解决方案,但其中 none 似乎有效

对我来说没有问题....

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        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());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            JTextField textField = new JTextField("This is a test");
            add(textField, gbc);

            JButton button = new JButton("This is a button");
            add(button, gbc);
            button.setFocusable(false);
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (textField.getCaretPosition() != 0) {
                        textField.setCaretPosition(0);
                    } else {
                        textField.setCaretPosition(textField.getText().length());
                    }
                    textField.requestFocusInWindow();
                }
            });
        }

    }

}

如果您还有问题,请提供 runnable example which doesn't work

更新为 JFormattedTextField...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        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());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            JFormattedTextField textField = new JFormattedTextField("This is a test");
            textField.setValue(0.8d);
            add(textField, gbc);

            JButton button = new JButton("This is a button");
            add(button, gbc);
            button.setFocusable(false);
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (textField.getCaretPosition() != 0) {
                        textField.setCaretPosition(0);
                    } else {
                        textField.setCaretPosition(textField.getText().length());
                    }
                    textField.requestFocusInWindow();
                }
            });
        }

    }

}

更新为“设置在开头”

好吧,我只想指出,我个人不喜欢 JFormattedTextField,它有时会做很多“事情”,但并不总是有意义。

我使用的一个“旧”技巧,在实现“自动 select 全部聚焦增益”时,将请求卸载到事件调度线程的末尾,这将请求置于 AFTER JFormattedTextField 在字段聚焦时所做的所有“时髦的事情”...

JFormattedTextField textField = new JFormattedTextField("This is a test");
textField.setValue(0.8d);
add(textField, gbc);
textField.addFocusListener(new FocusAdapter() {
    @Override
    public void focusGained(FocusEvent arg0) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                textField.setCaretPosition(textField.getText().length());
            }
        });
    }
});

是的,我是认真的...