我利用一些JFormattedTextFields在我的程序。出于某种原因,当文本字段收益中的文本字段点击焦点后,插入位置总是跳转到左侧(位置0)。我想插入符号在用户点击的位置结束。所以,如果我点击两个数字之间,光标应该在这两个数字之间结束了。

所以,我实现了一个的FocusListener,将获得的点击位置,并设置插入符位置在那里。

FocusListener focusListener = new FocusListener(){


    public void focusGained(FocusEvent evt) {

        JFormettedTextField jftf = (JFormattedTextField) evt.getSource();

        //This is where the caret needs to be.
        int dot = jftf.getCaret().getDot(); 

        SwingUtilities.invokeLater( new Runnable() {

        public void run() {
'the textField that has focus'.setCaretPosition('Some how get the evt or dot');              
              }
           });
        }

    public void focusLost (FocusEvent evt) {}

    });

我已经尝试了一些事情让他的工作。我已经使用了final关键字,其中工程尝试,但只有一个文本框。

我用设置/获取焦点侦听器内的方法来分配当前对象,但我不知道如何使这个“安全”(例如:他们需要同步?)。

也许有我丢失的东西?

有帮助吗?

解决方案

您需要使用的MouseListener:

MouseListener ml = new MouseAdapter()
{
    public void mousePressed(final MouseEvent e)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JTextField tf = (JTextField)e.getSource();
                int offset = tf.viewToModel(e.getPoint());
                tf.setCaretPosition(offset);
            }
        });
    }
};

formattedTextField.addMouseListener(ml);

其他提示

这实际发生在AbstractFormatter.install(JFormattedTextField),当字段获得焦点被调用。

我不知道为什么它是这样设计的,但是你可以重写此行为(只要你的格式不改变在该领域的字符串的长度。)

实施例(假定字段值int):

class IntFormatter extends AbstractFormatter {
    @Override
    public void install(final JFormattedTextField ftf) {
        int prevLen = ftf.getDocument().getLength();
        int savedCaretPos = ftf.getCaretPosition();
        super.install(ftf);
        if (ftf.getDocument().getLength() == prevLen) {
            ftf.setCaretPosition(savedCaretPos);
        }
    }

    public Object stringToValue(String text) throws ParseException {
        return Integer.parseInt(text);
    }

    public String valueToString(Object value) throws ParseException {
        return Integer.toString(((Number) value).intValue());
    }
}

请注意,这是不一样的默认Integer格式化。默认格式化器利用分开的组数位的DecimalFormat,例如"1,000,000"。这使得任务更难,因为它改变了字符串的长度。

在finnw的解决方案改进了一下我的想法。例如:

public static void main(String[] args) {
    NumberFormat format = NumberFormat.getInstance();
    NumberFormatter formatter = new NumberFormatter(format) {
        @Override
        public void install(JFormattedTextField pField) {
            final JFormattedTextField oldField = getFormattedTextField();
            final int oldLength = pField.getDocument().getLength();
            final int oldPosition = pField.getCaretPosition();

            super.install(pField);

            if (oldField == pField && oldLength == pField.getDocument().getLength()) {
                pField.setCaretPosition(oldPosition);
            }
        }
    };
    JFormattedTextField field = new JFormattedTextField(formatter);
    field.setValue(1234567890);

    JOptionPane.showMessageDialog(null, field);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top