[英]JavaFX CheckBoxTableCell catch ClickEvent
在TableView
使用CheckBoxTableCell
我不想在用戶單擊復選框時執行一些代碼。 需要在檢查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
列表(到目前為止只有一個)。 當DataHandler
調用onChange
事件時,將執行以下代碼:
@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;
}
你在這里看到的是我試圖反轉已更改的屬性...但復選框仍保持選中狀態。 因此,我正在尋找一種在更改Property之前執行檢查的方法。
基於CheckBoxTableCell
的文檔:
如果希望收到更改通知,建議直接觀察
CheckBox
操作的布爾屬性。
我不是說使用CheckBoxTableCell
是不可能的,但很可能它並不是那么簡單。
使用EventFilter
可以在大多數情況下管理這種“預選”事件。
因此,您可以嘗試將普通的TableColumn
與使用這些EventFilter
的相應cellFactory
使用。
我的例子
使用過的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
並向此CheckBox
添加兩個EventFilter
。 第一個是在鼠標按下時執行的,第二個是在按鍵上執行的(這里使用了KeyCode.SPACE
)。 他們都調用了validate
方法。 validate
方法使用事件(確保CheckBox
的選擇狀態未被修改),“驗證”輸入(我沒有驗證)然后顯示確認對話框。 如果用戶同意,則設置CheckBox
的selectedProperty
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.