Wählen Sie alle Daten starten, wenn JTable Zelle Bearbeitung
-
05-07-2019 - |
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.
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 ..