私はしばらく作業してきた編集可能なテーブルセルファクトリを使用しています。私は現在、編集を開始するためのシングルクリックを可能にする機能を実装しています。TableView JavaFxのすべてのセルに対してcancelEditを呼び出す
セル編集を開始するクリックが1回ありますが、別のセルを1回クリックすると前のページが閉じません。クリックしたセルを編集する前に、cancelEdit()
を呼び出すすべてのセルをループすることが私の考えでした。
以下は、私が使用しているセルクラス全体です(ダブルクリックで編集しても問題ありません)。作業中のセクションはコンストラクタにあります。
public class EditingCell<S, T> extends TableCell<S, T> {
private TextField textField;
public EditingCell() {
TableView<S> table = this.getTableView();
addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
for(TableColumn<S, ?> col : table.getColumns()) {
// cancelEdit() on all cells here
}
startEdit();
}
});
}
public void commit(Object val) {
commit(val, this.getTableRow().getIndex(), getTableView().getColumns().indexOf(this.getTableColumn()));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void commit(Object val, int row, int col) {
// Get the table
TableView<S> t = this.getTableView();
// Get the selected row/column
S selectedRow = t.getItems().get(row);
if (selectedRow == null)
return;
TableColumn<S, ?> selectedColumn = t.getColumns().get(col);
// Get current property name
String propertyName = ((PropertyValueFactory) selectedColumn.getCellValueFactory()).getProperty();
// Create a method name conforming to java standards (setProperty)
propertyName = ("" + propertyName.charAt(0)).toUpperCase() + propertyName.substring(1);
// Try to run the update
try {
// Type specific checks - could be done inside each
// setProperty() method
if (val instanceof Double) {
Method method = selectedRow.getClass().getMethod("set" + propertyName, double.class);
method.invoke(selectedRow, (double) val);
}
if (val instanceof String) {
Method method = selectedRow.getClass().getMethod("set" + propertyName, String.class);
method.invoke(selectedRow, (String) val);
}
if (val instanceof Integer) {
Method method = selectedRow.getClass().getMethod("set" + propertyName, int.class);
method.invoke(selectedRow, (int) val);
}
} catch (Exception e) {
e.printStackTrace();
}
// CommitEdit for good luck
commitEdit((T) val);
TableUtils.Refresh(t, t.getItems());
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
String val = "0.0";
if (!textField.getText().equals(""))
val = "" + Double.parseDouble(textField.getText());
setText(NumberUtils.roundTo2(NumberUtils.parseDouble(val)) + "");
setGraphic(null);
}
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText("");
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(NumberUtils.roundTo3(NumberUtils.parseDouble(getString())) + "");
setGraphic(null);
}
}
}
@SuppressWarnings({ "rawtypes" })
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
if (!arg2) {
if (textField.getText().equals(""))
commit(0.0);
else {
double val = Double.parseDouble(textField.getText());
commit(val);
}
}
}
});
textField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.ESCAPE) {
textField.setText("" + getItem());
cancelEdit();
event.consume();
}
// Navigate up and down in table
else if (event.getCode() == KeyCode.ENTER) {
TableView<S> table = getTableView();
int row = table.getEditingCell().getRow();
// Commit changes
if (textField.getText().equals(""))
commit(0.0);
else {
double val = Double.parseDouble(textField.getText());
commit(val);
}
// Do move
if (event.isShiftDown())
table.edit(row - 1, getTableColumn());
else {
table.edit(row + 1, getTableColumn());
}
}
// Move left and right in table
else if (event.getCode() == KeyCode.TAB) {
TableView<S> table = getTableView();
int row = table.getEditingCell().getRow();
// Save changes
if (textField.getText().equals(""))
commit(0.0);
else {
double val = Double.parseDouble(textField.getText());
commit(val);
}
ArrayList<TableColumn<S, ?>> cols = new ArrayList<TableColumn<S, ?>>();
int index = 0;
for (TableColumn<S, ?> c : table.getColumns()) {
if (c.isVisible() && c.isEditable())
cols.add(c);
if (c == getTableColumn())
index = cols.size() - 1;
}
// Do move
if (event.isShiftDown()) {
try {
TableColumn<S, ?> prevCol = cols.get(index - 1);
table.edit(row, prevCol);
} catch (Exception e) {
}
} else {
try {
TableColumn<S, ?> nextCol = cols.get(index + 1);
table.edit(row, nextCol);
} catch (Exception e) {
}
}
}
});
textField.setTextFormatter(new TextFormatter<String>((Change c) -> {
String text = c.getText();
TableView<S> table = getTableView();
if (table.getSelectionModel().getSelectedCells().size() == 0) {
return c;
}
TablePosition pasteCellPosition = table.getSelectionModel().getSelectedCells().get(0);
int clipRow = 0;
int clipCol = 0;
String curCellText = text;
if (text.contains("\t") || text.contains("\n")) {
StringTokenizer row = new StringTokenizer(text, "\n");
boolean hasRun = false;
while (row.hasMoreTokens() || !hasRun) {
String r = row.nextToken();
StringTokenizer col;
if (r != null)
col = new StringTokenizer(r, "\t");
else
col = new StringTokenizer(text, "\t");
hasRun = true;
clipCol = 0;
while (col.hasMoreTokens()) {
String content = col.nextToken();
if (clipRow == 0 && clipCol == 0) {
curCellText = content;
}
// calculate the position in the table cell
int rowTable = pasteCellPosition.getRow() + clipRow;
int colTable = pasteCellPosition.getColumn() + clipCol;
// Skip hidden columns before current cell
for (int i = 0; i < colTable; i++)
if (!table.getColumns().get(i).isVisible())
colTable++;
// Skip hidden columns between current and goal
while (!table.getColumns().get(colTable).isVisible()) {
if (colTable >= table.getColumns().size())
break;
colTable++;
}
// Add row if we reach the end
if (rowTable >= table.getItems().size()) {
if (table.getItems().get(0) instanceof EditableTableRow)
((EditableTableRow) table.getItems().get(0)).addRowToTable(table);
// continue;
}
if (colTable >= table.getColumns().size()) {
continue;
}
try {
double val = Double.parseDouble(content);
commit(val, rowTable, colTable);
} catch (Exception e) {
try {
int val = Integer.parseInt(content);
commit(val, rowTable, colTable);
} catch (Exception e2) {
commit(content, rowTable, colTable);
}
}
clipCol++;
}
clipRow++;
}
}
c.setText(curCellText);
return c;
}));
textField.requestFocus();
textField.selectAll();
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
を行うことができますが、[TextFieldTableCell]を使用していない理由(http://docs.oracle.com/javaseがあります/8/javafx/api/javafx/scene/control/cell/TextFieldTableCell.html)クラス? – VGR
主な理由 - 私はちょうど今存在していることを知りました.....しかし、私は機能に多くの変更を加えたので、それをそのままにしておくと思います。(表示された数字と実際の数字を切り取り、 – Chris