3

默认情况下,当 JTextField 获得焦点时,插入符号位于文本的开头。但是,我认为更好的行为是将它放在最后,或者选择所有文本,例如http://jsfiddle.net/Marcel/jvJzX/。有什么好方法可以做到这一点?理想情况下,该解决方案将全局应用于应用程序中的所有 JTextField。

默认行为示例(点击选项卡以聚焦该字段):

public static void main(String[] args) {
    JTextField field = new JTextField("hello world!");
    JOptionPane.showMessageDialog(null, field);
}

编辑:澄清一下,如果我不必搜索我的应用程序并更改所有文本字段,那就太好了。

4

3 回答 3

6

实际行为和要求均未得到完整描述:

当 JTextField 获得焦点时,插入符号位于文本的开头

这并不完全正确:当它获得焦点时

  • 单击,插入符号放置在鼠标位置
  • 其他方式(选项卡,程序化)它被放置在失去焦点时的位置。

因此,要求:

更好的行为是将它放在最后,或者选择所有文本

需要对这些情况进行一些思考,以免破坏可用性,至少对于第一个用户来说,如果鼠标手势被否决,可能会感到困惑。第二个是有争议的,可能取决于 OS/LAF。就个人而言,如果插入符号的位置不在开头,我不会触摸它。

从技术上讲,在焦点更改时全局触发组件状态更改的解决方案是向 KeyboardFocusManager 注册 PropertyChangeListener:

PropertyChangeListener pl = new PropertyChangeListener() {

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (!(evt.getNewValue() instanceof JTextField)) return;
        JTextField field = (JTextField) evt.getNewValue();
        // crude check to not overdo it
        int dot = field.getCaretPosition();
        if (dot == 0) {
            field.selectAll();
        }
    }
};
KeyboardFocusManager.getCurrentKeyboardFocusManager()
    .addPropertyChangeListener("permanentFocusOwner", pl);
于 2013-07-03T10:18:57.243 回答
3

FocusListener在字段中添加一个

触发时focusGained,将字段的插入符号位置设置为文本的末尾...

field.setCaretPosition(field.getDocument().getLength());

有关更多详细信息,请参阅如何编写焦点侦听器

更新

要选择所有文本,您可以使用...

field.selectAll();

这会将光标移动到末尾。

我过去所做的是创建一个实用程序类(AutoSelectOnFocusManager例如),它有一个FocusListener. 基本上,您使用它注册(或取消注册)JTextComponents,它会为您管理流程。节省大量重复代码:P

更新了一个简单的例子

做了这个简单的例子来测试评论中的反馈,我以为我也会加入......

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Wackme {

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

    public Wackme() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JTextField field1 = new JTextField("Some text", 20);
                JTextField field2 = new JTextField("Some text", 20);

                field1.addFocusListener(new FocusAdapter() {
                    @Override
                    public void focusGained(FocusEvent e) {
                        System.out.println("Move to end");
                        JTextField field = ((JTextField)e.getComponent());
                        field.selectAll();
                        //field.setCaretPosition(field.getDocument().getLength());
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(field1);
                frame.add(field2);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
于 2013-07-03T07:31:08.600 回答
-2

您需要创建您的自定义 jtextfield 并覆盖您想要的必要方法并执行您想要选择所有获得焦点的值然后在该方法中编写代码的步骤

于 2013-07-03T07:33:13.750 回答