Ограниченный выбор в JTextField / JTextComponent? - PullRequest
4 голосов
/ 14 сентября 2011

Рассмотрим JFormattedTextField (или любой JTextComponent, на самом деле), в котором есть префикс и суффикс, отображаемый вокруг фактического «текста» поля.

Например, двойным 3,5 будет строка (через форматирование) «3,50», вокруг которой будет префикс «$» и суффикс «», для отображаемого текста «$ 3,50».

Понятно, что это просто сделать. Тем не менее, пользователю все еще разрешено выбирать текст в префиксе / суффиксе, поэтому он может удалить часть или весь префикс / суффикс. Я бы предпочел, чтобы пользователь был ограничен таким образом, чтобы префикс / суффикс не мог быть выбран вообще (хотя он все еще является частью текстового поля, поэтому нет JLabels). Я почти могу сделать это с помощью CaretListener (или путем переопределения setCaretPosition / moveCaretPosition), который не позволяет C-a выбрать все поле, и не позволяет использовать клавиши со стрелками для перехода в префикс / суффикс. Тем не менее, перетаскивание мышью и клавиши со стрелками вправо позволяют выделению перемещаться в эти ограниченные области.

Есть идеи?

1 Ответ

6 голосов
/ 14 сентября 2011

Вы можете использовать NavigationFilter для этого.

Вот пример для начала:

import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class NavigationFilterPrefixWithBackspace extends NavigationFilter
{
    private int prefixLength;
    private Action deletePrevious;

    public NavigationFilterPrefixWithBackspace(int prefixLength, JTextComponent component)
    {
        this.prefixLength = prefixLength;
        deletePrevious = component.getActionMap().get("delete-previous");
        component.getActionMap().put("delete-previous", new BackspaceAction());
        component.setCaretPosition(prefixLength);
    }

    public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias)
    {
        fb.setDot(Math.max(dot, prefixLength), bias);
    }

    public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias)
    {
        fb.moveDot(Math.max(dot, prefixLength), bias);
    }

    class BackspaceAction extends AbstractAction
    {
        public void actionPerformed(ActionEvent e)
        {
            JTextComponent component = (JTextComponent)e.getSource();

            if (component.getCaretPosition() > prefixLength)
            {
                deletePrevious.actionPerformed( null );
            }
        }
    }

    public static void main(String args[]) throws Exception {

        JTextField textField = new JTextField("Prefix_", 20);
        textField.setNavigationFilter( new NavigationFilterPrefixWithBackspace(7, textField) );

        JFrame frame = new JFrame("Navigation Filter Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(textField);
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

Я полагаю, что именно так работает JFormattedTextField.Поэтому я не уверен, что вы можете использовать это с форматированным текстовым полем, поскольку оно может заменить поведение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...