簡単な解決策の1つは
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
が唯一の文字列カラムに適して提案しました。問題は、たとえば、編集中の列の浮動小数点型がある場合、対応するセルに空の文字列を入力し、ウィンドウの他のコントロールをクリックすることです。NullPointerException
をCellEditorRemover.propertyChange()
メソッドJTable.java
にスローします。この場合はgetCellEditor()
コールを使用して編集を中止またはキャンセルしますが、この場合はnull
を返します。入力された値が空でない場合、またはterminateEditOnFocusLost
フラグをすべて削除しても問題ありません。おそらく、説明されている状況はバグです。
私は前の投稿のいずれかに基づいて解決策を提供できることを願っています。それは私が前に仮定したようにそれほど些細なことではないが、それは私のように見える。 デフォルトのセルエディタから自分自身のセルエディタを継承し、JTextField
のテキストフィールドはFocusListener
です。このフォーカスリスナーは、セルの編集でフォーカスが失われ、フォーカスがウィンドウの別のコントロールで取得されたときに正常に機能します。しかし、セル選択の変更の場合、フォーカスリスナーは「ろう者」である。そのため、入力値が無効であれば、復元を開始する前に以前は有効な値を覚えておく必要があります。
以下のコードを参照してください。 Double
、Float
とInteger
でテストされましたが、これもByte
とString
で動作することを願っています。
フォーカスリスナーを持つテキストフィールド:
public class TextFieldCell extends JTextField {
public TextFieldCell(JTable cellTable) {
super(); // calling parent constructor
final JTable table = cellTable; // this one is required to get cell editor and stop editing
this.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
}
// this function successfully provides cell editing stop
// on cell losts focus (but another cell doesn't gain focus)
public void focusLost(FocusEvent e) {
CellEditor cellEditor = table.getCellEditor();
if (cellEditor != null)
if (cellEditor.getCellEditorValue() != null)
cellEditor.stopCellEditing();
else
cellEditor.cancelCellEditing();
}
});
}
}
デフォルトのセルエディタクラス:
class TextFieldCellEditor extends DefaultCellEditor {
TextFieldCell textField; // an instance of edit field
Class<?> columnClass; // specifies cell type class
Object valueObject; // for storing correct value before editing
public TextFieldCellEditor(TextFieldCell tf, Class<?> cc) {
super(tf);
textField = tf;
columnClass = cc;
valueObject = null;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
TextFieldCell tf = (TextFieldCell)super.getTableCellEditorComponent(table, value, isSelected, row, column);
if (value != null) {
tf.setText(value.toString());
}
// we have to save current value to restore it on another cell selection
// if edited value couldn't be parsed to this cell's type
valueObject = value;
return tf;
}
@Override
public Object getCellEditorValue() {
try {
// converting edited value to specified cell's type
if (columnClass.equals(Double.class))
return Double.parseDouble(textField.getText());
else if (columnClass.equals(Float.class))
return Float.parseFloat(textField.getText());
else if (columnClass.equals(Integer.class))
return Integer.parseInt(textField.getText());
else if (columnClass.equals(Byte.class))
return Byte.parseByte(textField.getText());
else if (columnClass.equals(String.class))
return textField.getText();
}
catch (NumberFormatException ex) {
}
// this handles restoring cell's value on jumping to another cell
if (valueObject != null) {
if (valueObject instanceof Double)
return ((Double)valueObject).doubleValue();
else if (valueObject instanceof Float)
return ((Float)valueObject).floatValue();
else if (valueObject instanceof Integer)
return ((Integer)valueObject).intValue();
else if (valueObject instanceof Byte)
return ((Byte)valueObject).byteValue();
else if (valueObject instanceof String)
return (String)valueObject;
}
return null;
}
それはあなたが以下を追加する必要がテーブルの初期化のコード:
myTable.setDefaultEditor(Float.class, new TextFieldCellEditor(new TextFieldCell(myTable), Float.class));
myTable.setDefaultEditor(Double.class, new TextFieldCellEditor(new TextFieldCell(myTable), Double.class));
myTable.setDefaultEditor(Integer.class, new TextFieldCellEditor(new TextFieldCell(myTable), Integer.class));
・ホープこれは同じ問題を抱えている人を助けるでしょう。
2番目のリンクが機能していません。 : – Niroshan
一時的なメディアに保存されている集合的知識の文脈で人類のために学ばれるレッスン – alphazero
ウェイバックマシンはそれを持っていました。 –