Frage

Ich versuche, einen Tisch zu machen, wie Excel funktioniert. Das heißt, wenn ein Benutzer Daten in die Zellen einzufügen, beginnt der Inhalt in sie ausgewählt wird und durch die neuen Daten eingefügt verändert.

War es hilfreich?

Lösung

Sie können eine benutzerdefinierte Table für die Tabelle erstellen. Diese Klasse wird eine Instanzvariable eines TextField haben, lässt es textField nennen. Dann wird die getTableCellEditorComponent Methode könnte wie folgt aussehen:

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

Andere Tipps

einen benutzerdefinierten Editor Erstellen funktioniert gut, wenn Sie immer nur String-Daten in der Tabelle und brauchen nur einen einzigen Editor. Wenn Sie jedoch mehrere verschiedene Arten von Daten, wie String, Integer, Double, Währungen, Prozentsätze usw., die alle einen JTextField als Editor verwenden, dann müssen Sie mehrere benutzerdefinierte Editoren erstellen.

Sie können bis auf der Tabelle Select All Editor lesen für eine andere mögliche Lösung.

Beachten Sie, dass es auch eine andere Möglichkeit, können Sie JTable # prepareEditor wie folgt außer Kraft setzen:

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

Die Lösung oben funktioniert nicht, wenn durch einen Mausklick gestartet Bearbeitung.

Für manche Menschen ist die Lösung selectAll () in einer invokeLater () aufzurufen, so dass der Text, nachdem die Mausereignisse ausgewählt wird versandt wurden, aber das funktioniert nicht für mich (vielleicht weil ich Substance Look bin mit und fühlen?)

Swing-Interna bekommen mouse () Ereignis später und die Einfügemarke wieder ändern, wie in dieser Stack-Trace angezeigt:

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)

Hier ist meine Lösung: Hören Sie Caretposition Änderungen, und das erste Mal die Auswahl von allen zu keinem nach dem Zell Bearbeitung ausgewählt geht gestartet wird, ruft selectAll () erneut. Der caret Hörer kann durch eine benutzerdefinierte Zelle Editor installiert werden, wie hier gezeigt, oder in einem überschriebenen editCellAt () -Methode in einem benutzerdefinierten 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;
    }
}

Wenn Ihr Ziel ist es, die Zelle zu leeren, wenn die Bearbeitung beginnt, keine Notwendigkeit selectAll() zu verwenden. Einfach Wert auf null.

Implementierung Beispiel:

(zwingender getTableCellEditorComponent() in 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;
    }
};

Sie sollten auf ExtJS aussehen. Es ist eine ziemlich steile Lernkurve, obwohl ..

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top