使用CheckBoxTableCell
中的TableView
我不想在用户点击复选框时执行某些代码。
需要在检查CheckBox之前以及关联属性更改之前执行此代码。
由于CheckBoxTableCell
没有触发startEdit()
,commitEdit()
等等,我需要另外一点来处理我的代码。
updateItem()
为时已晚,因为价值已经在那里改变了。
有人知道我可以插入代码的任何其他地方吗?或者我最好只编写自己的CheckBoxTableCell?
对于那些想要进一步思考的人:当用户检查checkBox时,我想运行一个代码,检查他的决定是否可能导致他以后出现问题。当属性更改时,我有一个changeListener,它将新值上传到数据库。如果可能有任何问题(我的代码返回true)那么应该有强制性错误消息:"你真的想要这样做吗... blabla"并且只有当他确认应该实际检查复选框时,值才会更改并上传到数据库。
这就是我设置CheckBoxTableCell
的方式:
//init cell factories
Callback<TableColumn<PublicMovie, Boolean>, TableCell<PublicMovie, Boolean>> checkBoxCellFactory
= (TableColumn<PublicMovie, Boolean> p) -> new CheckBoxTableCell<>();
//Assign Column
allMoviesCheckBoxColumn = (TableColumn<PublicMovie, Boolean>) allMoviesTableView.getColumns().get(0);
//Set CellValueFactory
allMoviesCheckBoxColumn.setCellValueFactory(cellData -> cellData.getValue().getSomeBooleanProperty();
someBooleanProperty
有一个听众。当更改为true时,statusProperty
会更改为1
。
此代码段位于TableView
底层类的构造函数中。每当用户单击CheckBox时,它就会被执行。
this.status.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
DataHandler.fireOnChangedEvent(PublicMovieChangeListener.STATUS_CHANGED, getMovie(), newValue, oldValue);
});
DataHandler
包含Listeners
的列表(目前只有一个)。当onChange
:
DataHandler
事件时,将执行以下代码
@Override
public void onChange(int changeID, PublicMovie changedPublicMovie, Object newValue, Object oldValue) {
switch (changeID) {
case STATUS_CHANGED:
boolean mayUpdate = check();
//check is a placeholder for the code that checks for problems.
//It will return false if there might be a problem.
if(!mayUpdate){
mayUpdate = ErrorDialogs.getConfirmationDialog("Überfüllung!", header, content);
}
if (mayUpdate) {
updateMovie(changedPublicMovie);
} else {
changedPublicMovie.getStatusProperty().set((int) oldValue);
refreshAllMoviesTable();
}
break;
case THREE_DIM_CHANGED:
updateMovie(changedPublicMovie);
break;
case CHILDREN_CHANGED:
updateMovie(changedPublicMovie);
break;
}
您在此处看到的是我尝试撤消已更改的属性...但复选框仍保持选中状态。因此,我正在寻找一种在更改属性之前执行检查的方法。
答案 0 :(得分:2)
基于CheckBoxTableCell
的文档:
如果您希望收到更改通知,建议直接进行 观察由
CheckBox
操纵的布尔属性。
我不能说CheckBoxTableCell
是不可能的,但很可能不是那么简单。
这种&#34;预选&#34;在EventFilter
s。
因此,您可以尝试将普通TableColumn
与使用这些cellFactory
的相应EventFilter
一起使用。
我的例子
使用过的cellFactory
:
tableCol.setCellFactory(p -> {
CheckBox checkBox = new CheckBox();
TableCell<Person, Boolean> tableCell = new TableCell<Person, Boolean>() {
@Override
protected void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null)
setGraphic(null);
else {
setGraphic(checkBox);
checkBox.setSelected(item);
}
}
};
checkBox.addEventFilter(MouseEvent.MOUSE_PRESSED, event ->
validate(checkBox, (Person) cell.getTableRow().getItem(), event));
checkBox.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if(event.getCode() == KeyCode.SPACE)
validate(checkBox, (Person) cell.getTableRow().getItem(), event);
});
tableCell.setAlignment(Pos.CENTER);
tableCell.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
return tableCell;
});
和使用过的validate
方法:
private void validate(CheckBox checkBox, Person item, Event event){
// Validate here
event.consume();
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
// Set the checkbox if the user want to continue
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK)
checkBox.setSelected(!checkBox.isSelected());
}
做什么:
它呈现一个简单的CheckBox
,并向此EventFilter
添加两个CheckBox
。第一个是在鼠标按下时执行的,第二个是在按键上执行的(这里使用了KeyCode.SPACE
)。他们都调用validate
方法。 validate
方法使用该事件(确保CheckBox
的选择状态未被修改),&#34;验证&#34;输入(我没有验证)然后显示确认对话框。如果用户同意,则设置selectedProperty
的{{1}}。