フォーカス上のJFormattedTextFieldキャレット位置
-
18-09-2019 - |
質問
私は私のプログラムでは、いくつかのJFormattedTextFieldsを利用しています。テキストフィールドの利益がテキストフィールドをクリックした後焦点を当て、いくつかの理由で、キャレット位置は常に左(位置0)にジャンプします。私は、ユーザーがクリックした場所で終わるためにキャレットをしたいと思います。私は2桁の間でクリックした場合ので、キャレットは、これら二つの数字の間に終わる必要があります。
だから私は、クリック位置を取得し、そこにキャレット位置を設定しますの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) {}
});
私は彼が仕事を得るために多くのことを試みました。私は1つだけですTextFieldに、作品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);
}