Pergunta

Estou tentando fazer uma mesa que funcione como o Excel. Ou seja, quando um usuário começa a inserir dados nas células, o conteúdo é selecionado e alterado pelos novos dados inseridos.

Foi útil?

Solução

Você pode criar um TableCellEditor personalizado para sua tabela. Esta classe terá uma variável de instância de um TextField, vamos chamá -lo textField. Então o getTableCellEditorComponent o método poderia ficar assim:

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

Outras dicas

Criar um editor personalizado funciona bem se você tiver apenas dados de string na tabela e precisar apenas de um único editor. No entanto, se você tiver vários tipos diferentes de dados, como string, número inteiro, duplo, moedas, porcentagens etc., que usam um JTextfield como editor, é necessário criar vários editores personalizados.

Você pode ler no Tabela Selecione todos os editores Para outra solução possível.

Observe que há também outra possibilidade, você pode substituir o JTABLE#Prepareditor como o seguinte:

@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;
}

A solução acima não funciona quando a edição é iniciada por um clique do mouse.

Para algumas pessoas, a solução é chamar selectAll () em um Invokelater () para que o texto seja selecionado após os eventos do mouse terem sido despachados, mas isso não está funcionando para mim (possivelmente porque estou usando uma aparência de substância? )

Os internos de swing recebem um evento MouseReleased () mais tarde e altere o caret novamente, como mostrado neste rastreamento de pilha:

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)

Aqui está minha solução:Ouça as mudanças de posição de cuidados e, na primeira vez em que a seleção passa de todas selecionadas para nenhuma selecionada após o início da edição de células, ligue para o selectAll () novamente. O ouvinte do Caret pode ser instalado por um editor de células personalizado, como mostrado aqui, ou em um método de editCellat () substituído em um jtable personalizado.

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;
    }
}

Se o seu objetivo é esvaziar a célula quando a edição começa, não há necessidade de usar selectAll(). Simplesmente defina valor para null.

Exemplo de implementação:

(Substituindo getTableCellEditorComponent() dentro 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;
    }
};

Você deve olhar para extjs. Há uma curva de aprendizado bastante íngreme, no entanto ..

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top