当前位置: 首页 > 知识库问答 >
问题:

如何在JavaFx中创建自定义对话框而不使用任何“ButtonType”控件?

湛铭
2023-03-14

我想创建一个自定义的对话框,它只是显示选项(参见图1)。如果用户选择了其中一个选项,对话框将立即关闭并返回相应的结果。

到目前为止,我只能通过在对话框中添加一个任意的按钮类型来实现,通过使用setVisible(false)来隐藏它,并在单击选项的EventHandler中应用fire()

这个怪异的变通方法其实很管用,但在我看来却很不专业……
那么,如何在不使用按钮式把戏的情况下,以更专业或更恰当的方式做到这一点呢?

public class CustomDialog extends Dialog<String> {

    private static final String[] OPTIONS
            = new String[]{"Option1", "Option2", "Option3", "Option4"};
    private String selectedOption = null;
    Button applyButton;

    public CustomDialog() {
        super();
        initStyle(StageStyle.DECORATED);
        VBox vBox = new VBox();
        for (String option : OPTIONS) {
            Button optionButton = new Button(option);
            optionButton.setOnAction((event) -> {
                selectedOption = option;
                applyButton.fire();
            });
            vBox.getChildren().add(optionButton);
        }
        getDialogPane().setContent(vBox);
        getDialogPane().getButtonTypes().add(ButtonType.APPLY);
        applyButton = (Button) getDialogPane().lookupButton(ButtonType.APPLY);
        applyButton.setVisible(false);

        setResultConverter((dialogButton) -> {
            return selectedOption;
        });
    }
}
    CustomDialog dialog = new CustomDialog();
    Optional<String> result = dialog.showAndWait();
    String selected = null;
    if (result.isPresent()) {
        selected = result.get();
    } else if (selected == null) {
        System.exit(0);
    }

共有1个答案

皇甫喜
2023-03-14

对话框只是一个显示对话框窗格的窗口,并且引用对话框窗格的Javadocs:

DialogPane基于ButtonType的概念进行操作。ButtonType是应在对话框窗格中可视化表示的单个按钮的描述符。因此,创建DialogPane的开发人员必须指定要显示的按钮类型

(我的重点)。因此,虽然您已经展示了一种可能的解决方案,但在另一个答案中,Slaw展示了另一种解决方案,如果您试图使用dialog而不使用ButtonType及其关联的结果转换器,那么您实际上是在使用dialog类来处理它不想要处理的东西。

您描述的功能完全可以通过常规模式stage来实现。例如,下面给出了与您描述的相同的基本行为,并且不涉及ButtonTypes:

package org.jamesd.examples.dialog;

import java.util.Optional;
import java.util.stream.Stream;

import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;

public class CustomDialog {

    private static final String[] OPTIONS 
        = {"Option 1", "Option 2", "Option 3", "Option 4"};

    private final Stage stage ;

    private String selectedOption = null ;

    public CustomDialog() {
        this(null);
    }

    public CustomDialog(Window parent) {
        var vbox = new VBox();
        // Real app should use an external style sheet:
        vbox.setStyle("-fx-padding: 12px; -fx-spacing: 5px;");
        Stream.of(OPTIONS)
            .map(this::createButton)
            .forEach(vbox.getChildren()::add);
        var scene = new Scene(vbox);
        stage = new Stage();
        stage.initOwner(parent);
        stage.initModality(Modality.WINDOW_MODAL);
        stage.setScene(scene);
    }

    private Button createButton(String text) {
        var button = new Button(text);
        button.setOnAction(e -> {
            selectedOption = text ;
            stage.close();
        });
        return button ;
    }

    public Optional<String> showDialog() {
        selectedOption = null ;
        stage.showAndWait();
        return Optional.ofNullable(selectedOption);
    }
}

下面是一个使用此自定义对话框的简单应用程序类:

package org.jamesd.examples.dialog;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class App extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        var root = new VBox();
        // Real app should use an external style sheet:
        root.setStyle("-fx-padding: 12px; -fx-spacing: 5px;");
        var showDialog = new Button("Show dialog");
        var label = new Label("No option chosen");
        showDialog.setOnAction(e -> 
            new CustomDialog(stage)
                .showDialog()
                .ifPresentOrElse(label::setText, Platform::exit));
        root.getChildren().addAll(showDialog, label);
        stage.setScene(new Scene(root));
        stage.show();
    }

}
 类似资料:
  • 我想创建一个如下所示的自定义对话框 我试过以下几件事。 > 我创建了AlertDialog.Builder的子类,并使用了自定义标题和自定义内容视图,但结果不是预期的。 另一个尝试是子类DialogFragment并自定义onCreateDialog中的对话框,但结果并不像预期的那样。 然后我尝试使用一个普通的对话框类。结果不如预期。 在这三种情况下,问题是当我忽略标题视图时,对话框的大小不像预期

  • 问题内容: 我在JFrame上有一个按钮,当单击该按钮时,我希望对话框弹出并带有多个文本区域供用户输入。我一直在四处寻找解决方法,但是我一直感到困惑。有人可以帮忙吗? 问题答案: 如果您不需要太多自定义行为,则JOptionPane可以节省大量时间。它负责OK / Cancel选项的放置和本地化,并且是一种无需定义自己的类即可显示自定义对话框的快捷方法。大多数情况下,JOptionPane中的“

  • 问题内容: 我需要在JavaFX中创建一个对话框。我知道我可以通过修改模式,所有者和可调整大小的属性来使舞台表现得像对话框。 但是,如何从舞台窗口中隐藏“最小化”和“最大化”按钮?典型的对话框只有“关闭”按钮。 问题答案: 在Windows 7下,在显示窗口之前初始化为StageStyle.UTILITY将创建一个仅具有关闭按钮而没有最小化或最大化按钮的窗口: 如果您需要一整套基本的JavaFX对

  • 我需要用JavaFX创建一个对话框。我知道我可以通过修改modal、owner和resizable属性使Stage的行为像一个对话框。 但是我如何从舞台窗口隐藏“最小化”和“最大化”按钮呢?典型的对话框只有“关闭”按钮。

  • 问题内容: 有人可以告诉我如何创建与链接[here] [1]类似/完全相同的上述对话框视图,问题的重点是在图片的中心创建视图? 我已经进行了一些研究,这使我想知道我应该使用自定义xml创建自定义对话框视图还是应该使用alertdialog创建上面显示的确切视图可编程性?即使有alertdialog的可能,在给出alertdialog限制的情况下,我该如何容纳对话框图片中间显示的那么多textvie

  • 我想做的是:我想在android中创建一个圆角的自定义对话框。 正在发生的事情:我能够使自定义对话框,但它没有圆角。我试着添加一个选择器,但我仍然无法实现圆角。 下面是我的相同代码: Java代码: xml代码: