将焦点定位在焦点上的JTextField末尾的最佳方法是什么?

时间:2013-07-03 07:29:20

标签: java swing focus jtextfield caret

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

默认行为示例(点击标签以对焦字段):

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

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

3 个答案:

答案 0 :(得分:5)

实际行为和要求都没有完整描述:

  

当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);

答案 1 :(得分:3)

向字段

添加FocusListener

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

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

有关详细信息,请参阅How to write a focus listener

<强>更新

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

field.selectAll();

将光标移动到最后。

我过去所做的是创建一个实用工具类(例如AutoSelectOnFocusManager),它只有一个FocusListener。基本上,您使用它注册(或取消注册)JTextComponent,它会为您管理流程。保存了大量重复的代码: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);
            }
        });
    }
}

答案 2 :(得分:-2)

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