Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将插入符号放置在焦点上JTextField末尾的最佳方式是什么?_Java_Swing_Focus_Jtextfield_Caret - Fatal编程技术网

Java 将插入符号放置在焦点上JTextField末尾的最佳方式是什么?

Java 将插入符号放置在焦点上JTextField末尾的最佳方式是什么?,java,swing,focus,jtextfield,caret,Java,Swing,Focus,Jtextfield,Caret,默认情况下,当JTextField获得焦点时,插入符号位于文本的开头。但是,我认为更好的做法是将其放在末尾,或者选择所有文本,例如。做这件事的好方法是什么?理想情况下,该解决方案将全局应用于应用程序中的所有JTextFields 默认行为示例(点击tab以聚焦该字段): 编辑:为了澄清,如果我不必搜索我的应用程序并更改所有文本字段,那就太好了。在字段中添加一个FocusListener 触发focusgound时,将字段的插入符号位置设置为文本的结尾 field.setCaretPosition

默认情况下,当JTextField获得焦点时,插入符号位于文本的开头。但是,我认为更好的做法是将其放在末尾,或者选择所有文本,例如。做这件事的好方法是什么?理想情况下,该解决方案将全局应用于应用程序中的所有JTextFields

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


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

在字段中添加一个
FocusListener

触发
focusgound
时,将字段的插入符号位置设置为文本的结尾

field.setCaretPosition(field.getDocument().getLength());
有关更多详细信息,请参阅

已更新

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

field.selectAll();
这将把光标移到末端

我过去所做的是创建一个实用类(
autoselectionfocusmanager
),它有一个
FocusListener
。基本上,您可以使用它注册(或注销)
JTextComponent
s,它会为您管理流程。节省大量重复代码: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);
            }
        });
    }
}

您需要创建自定义jtextfield并覆盖所需的必要方法,并执行一些步骤,例如选择获得的焦点上的所有值,然后用该方法编写代码。实际行为和要求都没有完整描述:

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

我认为应该是
field.getDocument().getLength()-1
@MadProgrammer,但是XXX.selectAll()需要包装到
invokeLater
@mKorbel中,这取决于,我知道如果它是一个
JSpinner
它肯定是这样的。我认为当一个JFormattedTextField被自己使用或用作另一个组件的编辑器时,调用器是必需的。无论是这样,还是将光标放在末尾,这都可能是一个明显的区别,(我的观点)有两种方法可以使用插入符号移动到文档末尾,请参见@MadProgrammer提供的答案或selectAll()查看(@MadProgrammer)post+1中的我的评论,以获得简单的全局解决方案。
selectAll()
可能应该包装在SwingUtilities.invokeLater()中,否则JFormattedTextField上的选择将不起作用。@camickr说得好!虽然不能完全确定格式化文本字段的可用性,但它的navigationFilter可能有自己的想法?+1-您可能还需要检查
事件.getOldValue()
是否是一个JTextField,以便撤销
selectAll()
@splungebob这是一个值得考虑的好问题!可能取决于具体的要求,但-不完全确定我们是否总是想取消选择,即使在旧字段中选择了所有?
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);