문제

내 프로그램에서 몇 가지 JFormattedTextFields를 사용하고 있습니다. 텍스트 필드가 텍스트 필드를 클릭 한 후 텍스트 필드가 초점을 맞출 때 어떤 이유로, 캐럿 위치는 항상 왼쪽으로 이동합니다 (위치 0). 캐럿이 사용자가 클릭 한 위치에서 끝나기를 원합니다. 따라서 두 자리 숫자를 클릭하면 캐럿 이이 두 자리 사이에서 끝나야합니다.

그래서 클릭 위치를 가져 와서 캐럿 위치를 설정하는 Focus 목록을 구현했습니다.

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) {}

    });

나는 그의 일을하기 위해 많은 것들을 시도했다. 최종 키워드를 사용해 보았지만 작동하지만 단일 텍스트 필드에만 사용했습니다.

초점 리스너 내부에서 Set/Get 메소드를 사용하여 현재 객체를 할당했지만이 "안전한"방법에 대해서는 잘 모르겠습니다 (예 : 동기화해야합니까?).

내가 놓친 것이 있을까요?

도움이 되었습니까?

해결책

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), 필드가 집중할 때 호출됩니다.

왜 이런 식으로 설계된지 잘 모르겠지만,이 동작을 무시할 수 있습니다 (Formatter가 현장에서 문자열의 길이를 변경하지 않는 한).

예제 (필드 값이 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 형성. 기본 포맷터는 a를 사용합니다 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