Позиция курсора JFormattedTextField на фокусе

Я использую несколько 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) {}

    });

Я попробовал много вещей заставить его работать. Я попытался использовать заключительное ключевое слово, которое работает, но только для единственного текстового поля.

Я использовал, устанавливал/получал методы в слушателе фокуса для присвоения текущего объекта, но не уверен в том, как сделать этот "сейф" (например, они должны синхронизироваться?).

Возможно, существует что-то, что я пропускаю?

7
задан Jonas 22 December 2011 в 12:59
поделиться

2 ответа

Вам нужно использовать 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);
12
ответ дан 6 December 2019 в 09:19
поделиться

Мой $0.02:

Если этот метод виден извне (вызывается кодом, который вы не контролируете), то вам, вероятно, потребуется обработать возможность отправки вам недопустимого значения перечисления. В таком случае, сделайте исключение.

Если этот метод является внутренним для вашего кода (только вы его называете), то утверждение должно быть всем необходимым. Это уловит случай, когда когда-нибудь добавят новое значение перечисления и забудут обновить выписку по коммутатору.

Всегда предоставляйте случай по умолчанию в каждом коммутаторе и, по крайней мере, утверждайте, если он попадет. Эта привычка окупится за счет экономии часов или даже дней царапин головы каждый раз.

-121--1855980-

ActiveRecord используется для вызова after_save обратный вызов каждый раз, когда метод сохранения вызывается, даже если модель не была изменен и нет запроса на вставку/обновление породилась.

ActiveRecord executes:after_save обратные вызовы при каждом успешном сохранении записи независимо от того, была ли она изменена.

# record invalid, after_save not triggered
Record.new.save

# record valid, after_save triggered
r = Record.new(:attr => value)

# record valid and not changed, after_save triggered
r.save

Вы хотите знать, что запись будет изменена, а не сохранена. Это можно легко выполнить с помощью record.changed?

class Record

  after_save :do_something_if_changed

  protected

  def do_something_if_changed
    if changed?
      # ...
    end
  end
end
-121--4780094-

Это происходит в 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());
    }
}

Обратите внимание, что это не то же самое, что по умолчанию целочисленный форматер. Форматер по умолчанию использует DecimalFormat , разделяющий группы цифр, например «1 000 000» . Это усложняет задачу, поскольку она изменяет длину последовательности.

7
ответ дан 6 December 2019 в 09:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: