簡體   English   中英

JavaFX CheckBoxTableCell捕獲ClickEvent

[英]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的選擇狀態未被修改),“驗證”輸入(我沒有驗證)然后顯示確認對話框。 如果用戶同意,則設置CheckBoxselectedProperty

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM