焦点的JFormattedTextField插入位置
-
18-09-2019 - |
题
我利用一些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);
}
不隶属于 StackOverflow