如何确定在JavaFX ChoiceDialog中是否按下了取消

时间:2015-09-28 15:06:33

标签: javafx-8

我发现这个link显示了如何使用字符串来管理它,但是我不知道如何通过传递给ChoiceDialog的复杂对象来检查它

我有以下用例:

        ChoiceDialog<MyDTO> dialog = new ChoiceDialog<MyDTO>(null, dtoList);
        dialog.setContentText("Select Type");
        Optional<MyDTO> selected = dialog.showAndWait();

        if(!selected.isPresent() || selected.get().getType().equals(currentValue.getType())){
            //nothing selected
            //Display an error message since nothing was selected or changed.
            return;
        }

如果用户选择OK,我只想执行验证,而不是取消或关闭带有X的框。我试图使用该示例,但由于我的列表(如果不是字符串),那么它将无法工作。

谢谢!

2 个答案:

答案 0 :(得分:0)

我能够根据链接更改我的代码,使其工作,但是我发现这在解决方案方面非常差 - 所以我希望有一个比这更好,更直观的方法。 ..

    //Ensure a new type is chosen
    Collection<String> list = onlineList.stream().map(dto ->dto.getDisplayName()).collect(Collectors.toList());
    ChoiceDialog<String> dialog = new ChoiceDialog<String>(null, list);
    dialog.setContentText("Select Type Type");
    dialog.setResultConverter( ( ButtonType type ) -> {
        ButtonBar.ButtonData data = type == null ? null : type.getButtonData();
        if ( data == ButtonBar.ButtonData.OK_DONE ) {
            return "OK";
        } else {
            return null;
        }
    } );

    Optional<String> selectedType = dialog.showAndWait();

    if(selectedType.isPresent() && "OK".equals(selectedType.get())) {
        String typeName = dialog.getSelectedItem();
        String typeCode = onlineList.stream().filter(dto -> typeName.equals(dto.getTypeName())).findFirst().get().getTypeCode();
        if(!typeCode.equals(currentValue.getTypeCode())) {
            //perform my work since this is a valid transition
        }else {
            //throw an error since the item wasn't changed
            return;
        }
    } 

答案 1 :(得分:0)

如果我理解正确,您希望显示带有一组选项的ChoiceDialog,但最初未选择任何内容。如果用户在没有选择的情况下点击“确定”,则要通知他们没有选择任何内容;但如果用户点击“取消”或关闭对话框,则不执行任何操作。

首先要注意的是,将null作为ChoiceDialog构造函数的默认选项传递似乎不起作用。解决方法是,使用默认构造函数,然后填充items列表。

由于用户按下“确定”,我看不到与空结果区分的漂亮方式,因为用户按下取消等等,结果为空(我猜你会做ChoiceDialog<Optional<MyDTO>>和从选择为空Optional开始。然后showAndWait()将返回Optional<Optional<MyDTO>>,如果按下取消,它将为空,但如果按下则会包含空Optional没有选择。)

为什么不在执行选择之前禁用“确定”按钮?您可以使用

执行此操作
dialog.getDialogPane().lookupButton(ButtonType.OK).
    disableProperty().
    bind(dialog.selectedItemProperty().isNull());

这是一个SSCCE:

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ChoiceDialog;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ChoiceDialogTest extends Application {

    @Override
    public void start(Stage primaryStage) {

        ObjectProperty<MyDTO> selected = new SimpleObjectProperty<>();

        Button button = new Button("Make choice");
        button.setOnAction(e -> {
            List<MyDTO> items = IntStream.rangeClosed(1, 10).
                    mapToObj(i -> new MyDTO("Item "+i, i)).
                    collect(Collectors.toList());

            ChoiceDialog<MyDTO> dialog = new ChoiceDialog<MyDTO>();

            dialog.getItems().addAll(items);

            dialog.getDialogPane().
                lookupButton(ButtonType.OK).
                disableProperty().
                bind(dialog.selectedItemProperty().isNull());

            dialog.showAndWait().ifPresent( choice -> {
                System.out.println(choice + " selected");
                selected.set(choice);               
            });
        });

        primaryStage.setScene(new Scene(new StackPane(button), 350, 120));
        primaryStage.show();
    }

    public static class MyDTO {
        private final StringProperty name = new SimpleStringProperty();
        private final IntegerProperty value = new SimpleIntegerProperty();

        public MyDTO(String name, int value) {
            setName(name);
            setValue(value);
        }

        public final StringProperty nameProperty() {
            return this.name;
        }

        public final java.lang.String getName() {
            return this.nameProperty().get();
        }

        public final void setName(final java.lang.String name) {
            this.nameProperty().set(name);
        }

        public final IntegerProperty valueProperty() {
            return this.value;
        }

        public final int getValue() {
            return this.valueProperty().get();
        }

        public final void setValue(final int value) {
            this.valueProperty().set(value);
        }

        @Override
        public String toString() {
            return getName() + " ("+getValue()+")";
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}