如何请求关注Javafx中的Dialog OK按钮?

时间:2016-01-07 12:18:01

标签: javafx javafx-2 javafx-8

如果在TextField上按下Enter键,如何获得对话框的OK按钮。我试过以下代码。但是在给出代码时,只要在“city_D”(TextField)上按下Enter键,就必须关注“确定”按钮。

package dialogdemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
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 {

    String street_1 = "";
    String street_2 = "";
    String city = "";

    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");

                TextField street_1_D = new TextField();
                TextField street_2_D = new TextField();
                TextField city_D = new TextField();

                Dialog<List<String>> dialog = new Dialog<>();
                dialog.setTitle("Address");
                dialog.setHeaderText(null);
                dialog.setGraphic(null);

                // Set the button types.
                ButtonType okButtonType = new ButtonType("Ok", ButtonBar.ButtonData.OK_DONE);

                dialog.getDialogPane().getButtonTypes().addAll(okButtonType, ButtonType.CANCEL);
                dialog.getDialogPane().setStyle("-fx-background-color: #fff;");

                VBox box = new VBox();
                VBox.setVgrow(box, Priority.ALWAYS);

                box.getChildren().addAll(street_1_D, street_2_D, city_D);
                dialog.getDialogPane().setContent(box);

                // Request focus on the username field by default.
                Platform.runLater(() -> street_1_D.requestFocus());

                // Dialog All Listner
                street_1_D.setOnKeyPressed(new EventHandler<KeyEvent>() {
                    public void handle(KeyEvent event) {
                        if (event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB || event.getCode() == KeyCode.DOWN) {
                            street_2_D.requestFocus();
                            event.consume();
                        }
                    }
                });
                street_2_D.setOnKeyPressed(new EventHandler<KeyEvent>() {
                    public void handle(KeyEvent event) {
                        if (event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB || event.getCode() == KeyCode.DOWN) {
                            city_D.requestFocus();
                            event.consume();
                        }
                        if (event.getCode() == KeyCode.UP) {
                            street_1_D.requestFocus();
                            event.consume();
                        }
                    }
                });
                city_D.setOnKeyPressed(new EventHandler<KeyEvent>() {
                    public void handle(KeyEvent event) {
                        if (event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB || event.getCode() == KeyCode.DOWN) {
                            //okButtonType.requestFocus();
                            event.consume();
                        }
                        if (event.getCode() == KeyCode.UP) {
                            street_2_D.requestFocus();
                            event.consume();
                        }
                    }
                });

                // END Dialog All Listner
                List<String> databaseFiles = new ArrayList<String>();
                dialog.setResultConverter(dialogButton -> {
                    if (dialogButton == okButtonType) {
                        street_1 = street_1_D.getText();
                        databaseFiles.add(street_1);
                        street_2 = street_2_D.getText();
                        databaseFiles.add(street_2);
                        city = city_D.getText();
                        databaseFiles.add(city);
                        return databaseFiles;
                    }
                    return null;
                });

                Optional<List<String>> result = dialog.showAndWait();
                if (result.isPresent()) {
                    System.out.println("Street 1: " + street_1 + " \n Street 2: " + street_2 + "\n City: " + city);
                } else {
                    System.out.println("Cancle");
                }
            }
        });

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

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

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

2 个答案:

答案 0 :(得分:1)

您可以从对话框窗格中获取按钮并请求焦点如下:

city_D.setOnKeyPressed(new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent event) {
        if (event.getCode() == KeyCode.ENTER ||
            event.getCode() == KeyCode.TAB ||
            event.getCode() == KeyCode.DOWN) {

            dialog.getDialogPane().lookupButton(okButtonType).requestFocus();
            event.consume();
        }
        if (event.getCode() == KeyCode.UP) {
            street_2_D.requestFocus();
            event.consume();
        }
    }
});

答案 1 :(得分:0)

首先,它听起来不像你真正想要的是“聚焦”在按钮上。要使按钮响应“Enter”,您需要将其设为“默认”按钮。最明显的方法是将按钮的DefaultButton属性绑定到city_D字段的Focused属性。

但是,您也可以在TextField上设置OnAction,当您点击&lt; Enter&gt;时会触发在文本字段上,这意味着你可以在没有OK按钮的情况下执行任何OK按钮。

此外,您可以将按钮的DefaultButton属性绑定到Button的Focused属性。然后当你在最后一个字段上点击“TAB”(将焦点传递给Button),然后“Enter”时,它将会激活。

就个人而言,我不会乱用UP,DOWN和ENTER遍历的东西。大多数人习惯使用TAB和SHIFT-TAB来移动屏幕,而其他东西只会使代码混乱而没有什么价值。如果你想这样做,我会考虑使用基于TraversalEngine的解决方案。

但如果你真的想使用&lt; Enter&gt;要移动到下一个字段,我会使用OnAction来完成它。这是一个展示所有这些东西混合的样本:

public class sampleFrame2 extends Application {

class TestPane extends BorderPane {

    private Label label;
    private TextField tf1 = new TextField();
    private TextField tf2 = new TextField();
    private TextField tf3 = new TextField();
    private Button button1 = new Button("the button");
    private Text text = new Text("Not set");

    public TestPane() {
        VBox vbox = new VBox();
        vbox.getChildren().addAll(tf1, tf2, tf3, button1, text);
        tf1.setOnAction(evt -> tf2.requestFocus());
        tf2.setOnAction(evt -> tf3.requestFocus());
        tf3.setOnAction(evt -> text.setText("From tf3"));
        button1.setOnAction(evt -> text.setText("From button1"));
        button1.defaultButtonProperty().bind(button1.focusedProperty());

        setCenter(vbox);
    }
}

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

@Override
public void start(Stage primaryStage) {

    Pane root = new TestPane();
    primaryStage.setScene(new Scene(root, 300, 250));
    primaryStage.show();
}

}