首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EventFilter用于ComboBox选定项

EventFilter用于ComboBox选定项
EN

Stack Overflow用户
提问于 2017-03-27 13:44:51
回答 2查看 738关注 0票数 0

如何为EventFilter的SelectedItem属性编写ComboBox?文章只对用户事件(如MouseEvent )进行描述,而且我似乎找不出selectedItem属性更改是什么。

我之所以这样问,是因为我在一个对话框中有一个3D应用程序,该应用程序在一个插槽上显示材料。该插槽可以与我的组合框进行切换,但我希望能够在所选内容发生实际更改之前进行筛选,查看是否有任何未保存的更改,并显示用户希望保存更改或中止的对话框。而且,由于我在组合框上有各种各样的侦听器,当combobox中的选择发生变化时,就会切换出3D中的材料,因此很难实现该对话框上的中止功能。

我也愿意接受“您想要保存更改”的其他方法吗?可能更适合的实现。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-27 15:55:44

考虑创建另一个属性来表示组合框中的值,并且只在用户确认时更新它。然后,应用程序的其余部分只需观察该属性即可。

因此,例如。

代码语言:javascript
复制
private ComboBox<MyData> combo = ... ;

private boolean needsConfirmation = true ;

private final ReadOnlyObjectWrapper<MyData> selectedValue = new ReadOnlyObjectWrapper<>();

public ReadOnlyObjectProperty<MyData> selectedValueProperty() {
    return selectedValue.getReadOnlyProperty() ;
}

public final MyData getSelectedValue() {
    return selectedValueProperty().get();
}

// ...

combo.valueProperty().addListener((obs, oldValue, newValue) -> {

    if (needsConfirmation) {
        // save changes dialog:
        Dialog<ButtonType> dialog = ... ;
        Optional<ButtonType> response = dialog.showAndWait();
        if (response.isPresent()) {
            if (response.get() == ButtonType.YES) {
                // save changes, then:
                selectedValue.set(newValue);
            } else if (response.get() == ButtonType.NO) {
                // make change without saving:
                selectedValue.set(newValue);
            } else if (response.get() == ButtonType.CANCEL) {
                // revert to old value, make sure we don't display dialog again:
                // Platform.runLater() is annoying workaround required to avoid
                // changing contents of list (combo's selected items) while list is processing change:
                Platform.runLater(() -> {
                    needsConfirmation = false ;
                    combo.setValue(oldValue);
                    needsConfirmation = true ;
                });
            }
        } else {
            needsConfirmation = false ;
            combo.setValue(oldValue);
            needsConfirmation = true ;
        }
    }
});

现在,您的应用程序只需观察selectedValueProperty()并在它发生更改时作出响应:

代码语言:javascript
复制
selectionController.selectedValueProperty().addListener((obs, oldValue, newValue) -> {
    // respond to change...
});

下面是一个(非常简单的) SSCCE:

代码语言:javascript
复制
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class InterceptComboBox extends Application {

    private ComboBox<String> combo ;
    private boolean needsConfirmation = true ;
    private Label view ;
    private final ReadOnlyObjectWrapper<String> selectedValue = new ReadOnlyObjectWrapper<String>();

    public ReadOnlyObjectProperty<String> selectedValueProperty() {
        return selectedValue.getReadOnlyProperty();
    }

    public final String getSelectedValue() {
        return selectedValueProperty().get();
    }

    @Override
    public void start(Stage primaryStage) {
        combo = new ComboBox<>();
        combo.getItems().addAll("One", "Two", "Three");
        combo.setValue("One");
        selectedValue.set("One");
        view = new Label();
        view.textProperty().bind(Bindings.concat("This is view ", selectedValue));

        combo.valueProperty().addListener((obs, oldValue, newValue) -> {
            if (needsConfirmation) {
                SaveChangesResult saveChanges = showSaveChangesDialog();
                if (saveChanges.save) {
                    saveChanges();
                }
                if (saveChanges.proceed) {
                    selectedValue.set(newValue);
                } else { 
                    Platform.runLater(() -> {
                        needsConfirmation = false ;
                        combo.setValue(oldValue);
                        needsConfirmation = true ;
                    });
                }
            }
        });

        BorderPane root = new BorderPane(view);
        BorderPane.setAlignment(combo, Pos.CENTER);
        BorderPane.setMargin(combo, new Insets(5));
        root.setTop(combo);

        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }

    private void saveChanges() {
        System.out.println("Save changes");
    }

    private SaveChangesResult showSaveChangesDialog() {
        DialogPane dialogPane = new DialogPane();
        dialogPane.setContentText("Save changes?");
        dialogPane.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO, ButtonType.CANCEL);
        Dialog<SaveChangesResult> dialog = new Dialog<>();
        dialog.setDialogPane(dialogPane);
        dialog.setResultConverter(button -> {
            if (button == ButtonType.YES) return SaveChangesResult.SAVE_CHANGES ;
            else if (button == ButtonType.NO) return SaveChangesResult.PROCEED_WITHOUT_SAVING ;
            else return SaveChangesResult.CANCEL ;
        });
        return dialog.showAndWait().orElse(SaveChangesResult.CANCEL);
    }

    enum SaveChangesResult {
        SAVE_CHANGES(true, true), PROCEED_WITHOUT_SAVING(true, false), CANCEL(false, false) ;

        private boolean proceed ;
        private boolean save ;

        SaveChangesResult(boolean proceed, boolean save) {
            this.proceed = proceed ;
            this.save = save ;
        }

    }

    public static void main(String[] args) {
        launch(args);
    }
}
票数 3
EN

Stack Overflow用户

发布于 2017-03-27 16:02:56

要做到这一点,您需要将一个ChangeListener添加到valueProperty() of ComboBox

下面是一个示例:

代码语言:javascript
复制
comboBox.valueProperty().addListener(new ChangeListener<Object>()
{
    @Override
    public void changed(ObservableValue observable, Object oldValue, Object newValue)
    {
        Optional<ButtonType> result = saveAlert.showAndWait();

        if(result.isPresent())
        {
             if(result.get() == ButtonType.YES)
             {
                 //Your Save Functionality
                 comboBox.valueProperty().setValue(newValue);
             }
             else
             {
                 //Whatever
                 comboBox.valueProperty().setValue(oldValue);
             }
        }
    }    
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43048178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档