我从offical tableview tutorial跟踪了示例13-11单元格编辑的替代解决方案,但我希望我的tableview
充当jtable
。这意味着当一个单元格获得焦点时,它就可以进行编辑了,使用箭头键或Enter键可以立即提交编辑并移动到下一个单元格。
这就是我到目前为止所做的:
首先,我添加了
table.getSelectionModel().setCellSelectionEnabled(true);
然后我尝试修改班级EditingCell
:
class EditingCell extends TableCell<Person, String> {
private TextField textField;
public EditingCell() {
}
@Override
public void updateSelected(boolean selected) {
super.updateSelected(selected);
if (selected) {
createTextField();
setText(null);
setGraphic(textField);
textField.requestFocus();
textField.selectAll();
} else {
String value = textField.getText();
if (value != null) {
commitEdit(value);
} else {
commitEdit(null);
}
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
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) {
commitEdit(textField.getText());
}
}
});
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if ((t.getCode() == KeyCode.ENTER) || (t.getCode() == KeyCode.UP) || (t.getCode() == KeyCode.DOWN) || (t.getCode() == KeyCode.LEFT) || (t.getCode() == KeyCode.RIGHT)) {
t.consume();
String value = textField.getText();
if (value != null) {
commitEdit(value);
} else {
commitEdit(null);
}
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
我得到的tableview
是一团糟 - 我必须单击Enter键两次才能结束编辑,它不会提交编辑,而是取消编辑。
有人能指出我正确的方向吗?
答案 0 :(得分:1)
遗憾的是,该教程缺少一些代码修补程序,这些修补程序稍后在TextFieldTableCell类中引入,以使ENTER正常工作(RT-34685 - Use onAction instead of onKeyPressed和RT-28132 - Call requestFocus())。
这是一个工作示例,它是TextFieldTableCell代码的简化版本,它还使用Node.fireEvent()在提交后移动到下一个单元格(模仿KeyPressed事件):
class EditingCell extends TableCell<Person, String>
{
private TextField textField;
public EditingCell()
{
}
@Override
public void startEdit()
{
if (!isEditable() || !getTableView().isEditable()
|| !getTableColumn().isEditable())
{
return;
}
super.startEdit();
if (isEditing())
{
if (textField == null)
{
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
// requesting focus so that key input can immediately go into
// the TextField (see RT-28132)
textField.requestFocus();
}
}
@Override
public void cancelEdit()
{
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@Override
public void updateItem(String item, boolean empty)
{
super.updateItem(item, empty);
if (empty)
{
setText(null);
setGraphic(null);
} else
{
if (isEditing())
{
if (textField != null)
{
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else
{
setText(getString());
setGraphic(null);
}
}
}
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)
{
commitEdit(textField.getText());
}
}
});
// Use onAction here rather than onKeyReleased (with check for
// Enter), as otherwise we encounter RT-34685
textField.setOnAction(t -> {
commitEdit(textField.getText());
t.consume();
});
textField.setOnKeyReleased(t -> {
if (t.getCode() == KeyCode.ESCAPE)
{
cancelEdit();
t.consume();
}
});
textField.setOnKeyPressed(new EventHandler<KeyEvent>()
{
@Override
public void handle(KeyEvent t)
{
if ((t.getCode() == KeyCode.UP) || (t.getCode() == KeyCode.DOWN)
|| (t.getCode() == KeyCode.LEFT)
|| (t.getCode() == KeyCode.RIGHT))
{
// Commit the current text
commitEdit(textField.getText());
// Let's move out simulating a key press in this Cell
KeyEvent event = new KeyEvent(t.getSource(), t.getTarget(),
KeyEvent.KEY_PRESSED, "", "", t.getCode(), false, false,
false, false);
EditingCell.this.fireEvent(event);
}
}
});
}
private String getString()
{
return getItem() == null ? "" : getItem().toString();
}
}
希望这有帮助!