Как заставить Caret в ячейке JTable отображаться слева после применения к ней MaskFormatter

После применения MaskFormatter к JFormattedTextField, а затем установки этого текстового поля в столбец в моем JTable, курсор начал появляться везде, где я нажимаю. Однако я хочу, чтобы каретка отображалась в самой левой позиции ячейки, независимо от того, где в ячейке щелкает пользователь. Я попробовал метод setCaretPositionMethod, но ничего не сделал. Я предполагаю, что есть какой-то прослушиватель таблицы, который заставляет курсор перемещаться туда, где пользователь щелкает, если бы я знал, что это за прослушиватель, я мог бы переопределить эту функцию.

SSCCE:

public class TableExample extends JFrame {
    public TableExample() {
        add(makeTable());
    }

    private JTable makeTable() {
        Object[][] tableData = {{"","a","b",""}, {"","c","d",""}};
        String[] columns = {"column1", "column2", "column3", "dobColumn"};
        JTable table = new JTable(tableData, columns);

        ////DOB column formats to dd/mm/yy
        TableColumn dobColumn = table.getColumnModel().getColumn(3);
        DateFormat df = new SimpleDateFormat("dd/mm/yy");
        JFormattedTextField tf = new JFormattedTextField(df);
        tf.setColumns(8);
        try {
            MaskFormatter dobMask = new MaskFormatter("##/##/##");
            dobMask.setPlaceholderCharacter('0');
            dobMask.install(tf);
        } catch (ParseException ex) {
             Logger.getLogger(TableExample.class.getName()).log(Level.SEVERE, null, ex);
        }

        ////Does nothing
        tf.setCaretPoisition(0);

        dobColumn.setCellEditor(new DefaultCellEditor(tf));

        return table;
    }

    public static void main(String[] args) {
        JFrame frame = new TableExample();
        frame.setSize( 300, 300 );
        frame.setVisible(true); 
    }
}

person user217339    schedule 09.10.2016    source источник


Ответы (1)


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

Однако этот оператор должен быть заключен в SwingUtilities.invokeLater(...), чтобы убедиться, что код выполняется после положения курсора по умолчанию в форматированном текстовом поле.

Другой вариант — переопределить метод isCellEditable(...) JTable. Однако этот подход повлияет на все редакторы в таблице.

Вот пример кода, который показывает, как «выбрать» текст при вызове редактора:

public boolean editCellAt(int row, int column, EventObject e)
{
    boolean result = super.editCellAt(row, column, e);
    final Component editor = getEditorComponent();

    if (editor != null && editor instanceof JTextComponent)
    {
        ((JTextComponent)editor).selectAll();

        if (e == null)
        {
            ((JTextComponent)editor).selectAll();
        }
        else if (e instanceof MouseEvent)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    ((JTextComponent)editor).selectAll();
                }
            });
        }

    }

    return result;
}
person camickr    schedule 09.10.2016
comment
Спасибо, добавление прослушивателя фокуса сделало именно то, что я хотел. Также по какой-то причине применение маски к столбцу в JTable применит маску только к первой ячейке, на которую я нажимаю в столбце. После того, как маска была уничтожена, я исправил эту проблему, воссоздав маску и прослушиватель фокуса внутри метода tableChanged(). Я разместил вопрос о проблеме здесь - person user217339; 10.10.2016