Excelのように機能する表を作成しようとしています。つまり、ユーザーがセルにデータを挿入し始めると、セルの内容が選択され、挿入された新しいデータによって変更されます。
6 に答える
テーブルのカスタム 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;
}
別の可能性もあることに注意してください。次のように 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;
}
上記の解決策は、編集がマウスクリックで開始された場合は機能しません。
一部の人々にとっての解決策は、invokeLater()でselectAll()を呼び出して、マウスイベントがディスパッチされた後にテキストが選択されるようにすることですが、これは私には機能しません(おそらくSubstanceのルックアンドフィールを使用しているためですか? )。
次のスタックトレースに示すように、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()を再度呼び出します。カレットリスナーは、ここに示すようにカスタムセルエディターでインストールすることも、カスタムJTableのオーバーライドされたeditCellAt()メソッドでインストールすることもできます。
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 を見る必要があります。ただし、かなり急な学習曲線があります..