Выбрать все данные при начале редактирования JTable Cell

StackOverflow https://stackoverflow.com/questions/1412252

Вопрос

Я пытаюсь создать таблицу, которая работает как Excel. Это означает, что когда пользователь начинает вставлять данные в ячейки, содержимое в них выбирается и изменяется новыми вставленными данными.

Это было полезно?

Решение

Вы можете создать собственный TableCellEditor для своей таблицы. Этот класс будет иметь переменную экземпляра TextField , назовем его textField . Тогда метод getTableCellEditorComponent может выглядеть следующим образом:

public Component getTableCellEditorComponent(JTable table, Object value, 
                             boolean isSelected, int row, int column ) {
    textField.setText(value.toString());
    textField.selectAll();
    return textField;
}

Другие советы

Создание пользовательского редактора работает хорошо, если в таблице есть только данные String, и вам нужен только один редактор. Однако если у вас есть несколько различных типов данных, таких как String, Integer, Double, валюты, проценты и т. Д., Которые все используют JTextField в качестве редактора, вам необходимо создать несколько пользовательских редакторов.

Вы можете ознакомиться с таблицей «Выбрать все» для другого возможного решения.

Обратите внимание, что есть и другая возможность, вы можете переопределить JTable # prepareEditor следующим образом:

@Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
    Component c = super.prepareEditor(editor, row, column);
    if (c instanceof JTextComponent) {
        ((JTextComponent) c).selectAll();
    } 
    return c;
}

Приведенное выше решение не работает, когда редактирование запускается щелчком мыши.

Для некоторых людей решение состоит в том, чтобы вызвать selectAll () в invokeLater (), чтобы текст выделялся после отправки событий мыши, но это не работает для меня (возможно, потому что я использую внешний вид вещества) и чувствуешь?)

Внутренние компоненты Swing позже получают событие mouseReleased () и снова изменяют каретку, как показано в этой трассировке стека:

at javax.swing.text.JTextComponent.fireCaretUpdate(Unknown Source)
at javax.swing.text.JTextComponent$MutableCaretEvent.fire(Unknown Source)
at javax.swing.text.JTextComponent$MutableCaretEvent.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI$Handler.repostEvent(Unknown Source)

Вот мое решение: Прослушайте изменения положения каретки, и в первый раз, когда выбор переходит из всех выбранных в ни один из выбранных после начала редактирования ячейки, снова вызовите selectAll (). Слушатель каретки может быть установлен с помощью специального редактора ячеек, как показано здесь, или с помощью переопределенного метода editCellAt () в пользовательском JTable.

private class SelectAllCellEditor extends DefaultCellEditor
{
    public SelectAllCellEditor( JTextField tf )
    {
        super( tf );
    }

    /**
     * Flag to ensure we only install the caret listener on the editor once.
     */
    boolean listenerInstalled   = false;
    /**
     * Primes the caret listener to override deselection when the first mouseReleased() event is reposted to the editor.
     */
    boolean overrideDeselection = false;

    @Override
    public Component getTableCellEditorComponent( JTable table , Object value , boolean isSelected , int row , int column )
    {
        final JFormattedTextField tf = ( JFormattedTextField ) super.getTableCellEditorComponent( table , value , isSelected , row , column );

        if( !listenerInstalled )
        {
            tf.addCaretListener( new CaretListener( )
            {
                int lastDot     = 0;
                int lastMark    = 0;

                @Override
                public void caretUpdate( CaretEvent e )
                {
                    if( overrideDeselection )
                    {
                        int length = tf.getText( ) == null ? 0 : tf.getText( ).length( );

                        boolean wasAllSelected = ( lastDot == 0 && lastMark == length ) || ( lastDot == length && lastMark == 0 );
                        boolean nowNoneSelected = ( e.getDot( ) == 0 && e.getMark( ) == 0 ) || ( e.getDot( ) == length && e.getMark( ) == length );

                        if( wasAllSelected )
                        {
                            // don't try to override again until the next time cell editing is started
                            overrideDeselection = false;

                            // only re-select all if the selection went to none; otherwise the user clicked the cell and dragged to select part of the text
                            if( nowNoneSelected )
                            {
                                tf.selectAll( );
                            }
                        }
                    }

                    lastDot = e.getDot( );
                    lastMark = e.getMark( );
                }
            } );
            listenerInstalled = true;
        }

        // Prime the caret listener to override deselection when the first mouseReleased() event is reposted to the editor.
        overrideDeselection = true;
        tf.selectAll( );
        return tf;
    }
}

Если ваша цель - очистить ячейку в начале редактирования, не нужно использовать selectAll () . Просто установите значение null .

Пример реализации:

(переопределяя getTableCellEditorComponent () в DefaultCellEditor )

TableCellEditor myCellEditor = new DefaultCellEditor(new JTextField()){
    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
                boolean isSelected, int row, int column)
    {
        // empty the cell on edit start
        delegate.setValue( (editorComponent instanceof JTextField)? null : value);
        return editorComponent;
    }
};

Вы должны взглянуть на extJS. Хотя есть довольно крутая кривая обучения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top