对话框在Javafx中不止一次被调用?

时间:2016-01-10 12:42:41

标签: javafx javafx-2 javafx-8

我已经尝试过以下代码。我面临的问题是,每按一次F2键,对话框就会打开两次。但是当我通过单击Label"忘记密码"打开对话框时,它工作正常。请帮帮我。

package dialogdemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @author vikassingh
 */
public class DialogDemo extends Application {

    @Override
    public void start(Stage primaryStage) {
        HBox beforeButtonBox = new HBox();
        HBox.setHgrow(beforeButtonBox, Priority.ALWAYS);
        HBox hboxspace3 = new HBox();
        HBox.setHgrow(hboxspace3, Priority.ALWAYS);
        Label forgotPasswodKeycode = new Label("F2");
        forgotPasswodKeycode.setStyle(" -fx-text-fill: #000 ; -fx-font-size: 20;  -fx-underline: true; -fx-font-weight: bold ;");
        Label forgotPasswod = new Label(" Forgot Password?");
        forgotPasswod.setStyle(" -fx-text-fill: #000 ; -fx-font-size: 20; -fx-font-weight: bold ;");
        beforeButtonBox.getChildren().addAll(forgotPasswodKeycode, forgotPasswod);

        StackPane root = new StackPane();
        root.getChildren().add(beforeButtonBox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Dialog Demo!");
        primaryStage.setScene(scene);
        primaryStage.show();
        root.requestFocus();

        //  Key listener 
        root.setOnKeyPressed(new EventHandler<KeyEvent>() {
            public void handle(KeyEvent event) {
                if (event.getCode() == KeyCode.TAB || event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.DOWN) {
                    // Do Something
                    event.consume();
                } else {
                    try {
                        event.consume();
                        keyAction(event.getCode().toString(), root, primaryStage);
                    } catch (Exception ex) {
                        Logger.getLogger(DialogDemo.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        });
        forgotPasswod.setOnMouseClicked(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                forgotPassword();
            }
        });
        // END Listner
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    // F1 & Esc Key Action
    public void keyAction(String keyCode, StackPane root, Stage rootStage) throws Exception {
        if (keyCode.equalsIgnoreCase("F2")) {
            forgotPassword();
        }
    }
    // End F1 & Esc Key Action

    // Forgot Password
    public void forgotPassword() {
        Dialog<List<String>> dialog = new Dialog<>();
        DialogPane dialogPane = dialog.getDialogPane();
        dialog.setTitle("Forgoods");
        dialog.setHeaderText(null);
        dialog.setGraphic(null);
        // Set the button types.
        ButtonType okButtonType = new ButtonType("Ok", ButtonBar.ButtonData.OK_DONE);
        ButtonType cancleButtonType = new ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);
        dialog.getDialogPane().getButtonTypes().addAll(okButtonType, cancleButtonType);

        // VBox
        VBox alertVBox = new VBox();
        VBox.setVgrow(alertVBox, Priority.ALWAYS);
        alertVBox.setPrefWidth(400.0);
        alertVBox.setSpacing(10);

        ToggleGroup group = new ToggleGroup();
        RadioButton button1 = new RadioButton("select first");
        button1.setToggleGroup(group);
        button1.setUserData("A");
        button1.setSelected(true);
        RadioButton button2 = new RadioButton("select second");
        button2.setToggleGroup(group);
        button2.setUserData("B");

        group.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
            public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) {
                if (group.getSelectedToggle() != null) {
                    System.out.println(group.getSelectedToggle().getUserData().toString());
                }
            }
        });

        alertVBox.getChildren().addAll(button1, button2);
        // END VBox

        dialog.getDialogPane().setContent(alertVBox);
        // Request focus on the username field by default.
        Platform.runLater(() -> dialogPane.lookupButton(okButtonType).requestFocus());

        List<String> databaseFiles = new ArrayList<String>();
        dialog.setResultConverter(dialogButton -> {
            if (dialogButton == okButtonType) {
                return databaseFiles; // return Something
            }
            return null;
        });
        Optional<List<String>> result = dialog.showAndWait();
        if (result.isPresent()) {
            // Do Something
        } else {
            // Do Something
        }
    }
    // END Forgot Password

}

1 个答案:

答案 0 :(得分:0)

如果按下的键足够长,则会多次触发事件处理程序。

您可以使用KEY_RELEASED事件,该事件应仅触发一次:

root.setOnKeyReleased(new EventHandler<KeyEvent>() {
    ...
});

或者你可以设置一个boolean来阻止对话框被多次打开(代码有点简化):

    root.setOnKeyPressed(new EventHandler<KeyEvent>() {

        private boolean dialogOpen = false;

        @Override
        public void handle(KeyEvent event) {
            if (!dialogOpen) {
                dialogOpen = true;

                Dialog dialog = ...;
                dialog.showAndWait();

                dialogOpen = false;
            }
        }

    });