【问题标题】:Get Display method to return boolean? - JavaFX获取显示方法以返回布尔值? -JavaFX
【发布时间】:2015-11-24 09:13:21
【问题描述】:

我有一个名为 GUI 的类来管理我的应用程序。当用户想在我的程序中删除他的帐户时,我希望弹出一个警告框并要求他确认或取消他的操作,这样他就不会意外删除他的帐户。

 package application;

 import javafx.geometry.Pos;
 import javafx.scene.Scene;
 import javafx.scene.control.Button;
 import javafx.scene.control.Label;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.VBox;
 import javafx.stage.*;

 /**
  * An Alert Box for the GUI
  * to display errors to the user.
  *
  */
public class AlertBox
{   
Stage window;

public boolean display(String title, String message)
{       
    boolean cancel = false;

    window = new Stage();                                                               // Create the stage.        

    window.initModality(Modality.APPLICATION_MODAL);                                    // If window is up, make user handle it.
    window.setTitle(title);
    window.setMinHeight(350);
    window.setMinWidth(250);

    VBox root = new VBox();                 // Root layout.

    Label warning = new Label(message);     // Message explaining what is wrong.

    HBox buttonLayout = new HBox();         // The yes and cancel button.

    Button yesButton = new Button("Yes");   // Yes button for the user.
    Button noButton = new Button("No");     // No button for the user.

    yesButton.setOnAction(e ->
    {
        cancel = false;
    });

    noButton.setOnAction(e ->
    {
        cancel = true;
    });
    buttonLayout.getChildren().addAll(yesButton, noButton);


    root.getChildren().addAll(warning, buttonLayout);
    root.setAlignment(Pos.CENTER);

    Scene scene = new Scene(root);
    window.setScene(scene);
    window.show();
}

/**
 * Closes the window and returns whether the user said yes or no.
 * @param variable
 * @return
 */
private boolean close(boolean variable)
{
    window.close();
    return variable;
}

}

我希望我的 GUI 类确切地知道当用户在 AlertBox 类中时发生了什么。用户是否单击是或否?所以我想把显示方法设为布尔值。这就是问题所在,我的事件侦听器表达式无法返回任何值,因为它位于 void 类型的回调中。然后我想,“哦,我会让 close 方法返回一个布尔值”。但后来我记得我调用的原始函数是:

AlertBox warning = new AlertBox;
boolean userWantsToDelete = warning.display("Warning!", "You are about to delete your account. Are you sure you would like to do this?");

希望 display 方法返回一个变量,而不是 close 方法。我也不能只打电话 close ,因为那是行不通的。我能做些什么来帮助解决这个问题?非常感谢。

【问题讨论】:

  • 这并不能回答你的问题,但是将EventHandler 接口传递给显示方法怎么样?
  • * 实际上最好在调用display 方法之前在你的类中设置它。

标签: java user-interface javafx


【解决方案1】:

您可以使用 JavaFX 警报轻松执行您的任务:

    Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
    alert.setTitle("Confirmation Dialog");
    alert.setHeaderText("Warning !");
    alert.setContentText("Are you sure you want to perform this action ?");

    Optional<ButtonType> result = alert.showAndWait();
    if (result.get() == ButtonType.OK) {
     // delete user
 }

result.get() 返回一个布尔值。因此,您可以通过在 if 条件内进行比较来检查用户是否单击了ButtonType.OKButtonType.CANCEL

这里有一个例子供你理解:

使用默认警报,您会得到两个按钮,一个是确定按钮,另一个是取消按钮。但是,如果您想自定义警报,您可以将自己的按钮类型添加到其中,如下所示:

ButtonType buttonTypeOne = new ButtonType("One");
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");

并将它们添加到警报中:

alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);

所以你可以检查用户按下了哪个按钮

Optional<ButtonType> result = alert.showAndWait();
if (result.get() == buttonTypeOne){
    // ... user chose "One"
} else if (result.get() == buttonTypeTwo) {
    // ... user chose "Two"
} else{
    // ... user chose "Three"
}

【讨论】:

  • 对不起,我恐怕一点都不懂。这些是 JavaFX 命令吗? .setContentText、.setHeaderText、.showAndWait() 等? Optional 是什么意思?
  • @Hatefiend 是的,他正在使用 JavaFX Dialog 类。
  • 不使用 Dialog 类你会怎么做?一定有办法通过使用我自己的类来做到这一点。
【解决方案2】:

如果没有EventHandler,我认为你做不到。如果你真的想使用自己的类,你可以这样做:

AlertBox alert = new AlertBox("title","message");
alert.setYesAction( e -> {
    //TO-DO
});
alert.setNoAction( e -> {
    //TO-DO
});
alert.showAndWait();

如果您想检查cancel的状态,无论用户是否按下按钮,您都可以致电:alert.isCanceled();

import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.*;

/**
 * An Alert Box for the GUI to display errors to the user.
 *
 */
public class AlertBox extends Stage {
    private boolean cancel = false;
    private EventHandler<ActionEvent> yesAction = null;
    private EventHandler<ActionEvent> noAction = null;

    public AlertBox(String title, String message) {
        super();
        initModality(Modality.APPLICATION_MODAL); // If window is up,
        // make user handle
        // it.
        setTitle(title);
        setMinHeight(350);
        setMinWidth(250);

        VBox root = new VBox(); // Root layout.

        Label warning = new Label(message); // Message explaining what is wrong.

        HBox buttonLayout = new HBox(); // The yes and cancel button.

        Button yesButton = new Button("Yes"); // Yes button for the user.
        Button noButton = new Button("No"); // No button for the user.

        yesButton.setOnAction(e -> {
            cancel = false;
            yesAction.handle(new ActionEvent());
        });

        noButton.setOnAction(e -> {
            cancel = true;
            noAction.handle(new ActionEvent());
        });
        buttonLayout.getChildren().addAll(yesButton, noButton);

        root.getChildren().addAll(warning, buttonLayout);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root);
        setScene(scene);
    }

    public void setYesAction(EventHandler<ActionEvent> yesAction){
        this.yesAction = yesAction;
    }
    public void setNoAction(EventHandler<ActionEvent> noAction){
        this.noAction = noAction;
    }

    public boolean isCanceled(){
        return cancel;
    }
}

【讨论】:

    【解决方案3】:

    您可以添加可变对象(MutableBool 类)作为传递参数。由于 Mutable Object 是作为指针传递的,因此您可以分配一个值以签出该方法。

    添加类:

    class MutableBool{
        private boolean value;
    
        public void setValue(boolean value) {
            this.value = value;
        }
    
        public boolean getValue() {
            return value;
        }
    }
    

    对您的代码进行一些更改:

    public boolean display(String title, String message, MutableBool answer){
        ...
        answer.setValue(true);
    }
    

    【讨论】:

    • 好的,我想:boolean variable = false(假设用户会拒绝)。 AlertBox warning = new AlertBox(); warning.display("Warning", "Be careful!", variable); 那么,在显示方法中,如果我更改variable 的值,它也会显示在我的GUI 类中吗?我不知道原始类型是通过引用传递的。
    • 这行不通。布尔类在 java 中是不可变的。您可以从外部访问实例答案,但不能对其进行更改。如果您为类/方法中的变量 answer 分配一个新值,则将在那里使用一个新对象,您无法从外部访问该对象。 (因为您从外部持有对旧实例的引用)您可以对可变对象执行类似的操作。
    • @DThought,对不起,我没有考虑到这一点。我改变了答案。
    • 我只是在想这个。像这样的东西如何工作真是太奇怪了,但只是传入一个布尔值就不行。这算不算糟糕的编程?
    • 你可以这样做,但是你怎么知道用户已经按下了按钮?
    【解决方案4】:

    或者你可以在主类中处理:

    package application;
    
    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.layout.BorderPane;
    
    public class Main extends Application {
        @Override
        public void start(final Stage primaryStage) {
        try {
            final BorderPane root = new BorderPane();
            final Scene scene = new Scene(root, 400, 400);
    
            final AlertBox warning = new AlertBox("Warning!",
                    "You are about to delete your account. Are you sure you  would like to do this?");    
    
                warning.addCancelListener(new ChangeListener<Boolean>() {
    
                @Override
                public void changed(final ObservableValue<? extends Boolean> observable, final Boolean oldValue, final Boolean newValue) {
                    if (newValue) {
                        System.out.println("Tschüss");
                    } else {
                        System.out.println("Thanks for confidence");
                    }
                }
            });
    
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }    
    
        public static void main(final String[] args) {
            launch(args);
        }    
    }
    
    package application;
    
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.beans.value.ChangeListener;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.stage.Modality;
    import javafx.stage.Stage;
    
    /**
     * An Alert Box for the GUI
     * to display errors to the user.
     */
    public class AlertBox {
        Stage window;
        ObjectProperty<Boolean> cancel = new SimpleObjectProperty<>(null);
    
        public AlertBox(final String title, final String message) {
            cancel.setValue(null);
            display(title, message);
        }
    
        private void display(final String title, final String message) {
            window = new Stage(); // Create the stage.
    
            window.initModality(Modality.APPLICATION_MODAL); // If window is up, make user handle it.
            window.setTitle(title);
            window.setMinHeight(350);
            window.setMinWidth(250);
            window.setAlwaysOnTop(true);
    
            final VBox root = new VBox(); // Root layout.
    
            final Label warning = new Label(message); // Message explaining  what is wrong.
    
            final HBox buttonLayout = new HBox(); // The yes and cancel button.
    
            final Button yesButton = new Button("Yes"); // Yes button for the user.
            final Button noButton = new Button("No"); // No button for the user.
    
            yesButton.setOnAction(e -> {
                cancel.set(false);
                close();
            });
    
            noButton.setOnAction(e -> {
                cancel.set(true);
                close();
            });
    
            buttonLayout.getChildren().addAll(yesButton, noButton);
    
            root.getChildren().addAll(warning, buttonLayout);
            root.setAlignment(Pos.CENTER);
    
            final Scene scene = new Scene(root);
            window.setScene(scene);
            window.show();
        }
    
        /**
         * Closes the window
         *
         * @param variable
         */
        private void close() {
            window.close();
        }
    
        public void addCancelListener(final ChangeListener<Boolean> listener) {
            cancel.addListener(listener);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-13
      • 1970-01-01
      • 2021-01-20
      • 2012-11-03
      • 1970-01-01
      • 2015-09-10
      • 2012-11-04
      • 2015-06-18
      相关资源
      最近更新 更多