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

StackPane中居中的弹出窗格

司徒耀
2023-03-14

在我正在开发的JavaFX程序中,我有一个StackPane。第一个孩子是一个边界窗格,里面有其他东西。

我希望能够显示弹出窗口,使弹出窗口以外的所有内容变暗,以产生额外的焦点。这就是为什么我创建了一个扩展StackPane的“DarkenStackPane”。在创建时(在构造函数中),它会向其子级添加一个不透明度为 0.0 的矩形。它有两个功能,变暗()和变亮()。darken() 具有从 0.0 到 0.5 的 FadeTransition,而 brighten() 则相反。

我在StackPane中添加了一个Pane,这调用了darken()函数。darken()函数首先将黑色矩形放在前面,然后将Pane放在前面。

它工作正常,但是StackPane会调整其所有子级的大小以适应其大小......我不希望这种情况发生。相反,我希望具有自己宽度和高度的弹出窗格在StackPane中居中。

我知道我可以用StackPane。setMargin(它适用于硬编码值),但我无法确定正确的边距,因为创建时窗格还没有父级。

当您的窗格添加到父级时,是否有任何方法被调用?

我尝试使用ChangeListener执行此操作,但我无法绑定匿名函数中的属性。

共有1个答案

昌博易
2023-03-14

考虑使用ControlsFX

ControlsFX库有一个名为“轻量级对话框”的功能,它执行相同的对话框覆盖效果。为这种解决方案使用预html" target="_blank">构建的库通常比滚动您自己的实现更好。

如果您选择推出自己的解决方案,而不是使用ControlsFX,请继续阅读。。。

解决办法

将堆栈窗格的叠加子窗格放在组中。

StackPane stack = new StackPane(mainPane, new Group(popupPane)); 

为什么这工作

组是不可调整大小的,因此其效果是主窗格可调整大小,并且Popupane将假定其内部首选大小,并放置在一个组中,该组将由StackPane位于主窗格顶部的中心。

示范

我很久以前写的一个项目中的DialogFactory演示了这种在WebView上覆盖对话框的方法。下面的截图显示了在Java 8下运行willow-0.3-prerelease-jar并导航到http://www.w3schools.com/js/tryit.asp?filename=tryjs_alert,然后点击“尝试”按钮的输出。它所做的是将警告框(在JavaFX中呈现和编程,而不是JavaScript)覆盖在WebView控件的中心,该控件在显示警告时被禁用和变暗。

样本源

这是从柳树项目中选择的来源,它不是独立的,但您需要稍微调整它以采用它以适应您的情况。此处仅介绍代码以演示技术和模式。

/**
 * Overlay a dialog on top of the WebView.
 *
 * @param dialogNode the dialog to overlay on top of the view.
 */
private void overlayView(Node dialogNode) {
    // if the view is already overlaid we will just ignore this overlay call silently . . . todo probably not the best thing to do, but ok for now.
    if (!(webView.getParent() instanceof BorderPane)) return;

    // record the view's parent.
    BorderPane viewParent = (BorderPane) webView.getParent();

    // create an overlayPane layering the popup on top of the webview
    StackPane overlayPane = new StackPane();
    overlayPane.getChildren().addAll(webView, new Group(dialogNode));
    webView.setDisable(true);

    // overlay the popup on the webview.
    viewParent.setCenter(overlayPane);
}

/**
 * Removes an existing dialog overlaying a WebView.
 */
private void removeViewOverlay() {
    BorderPane viewParent = (BorderPane) webView.getParent().getParent();
    viewParent.setCenter(webView);
}

public EventHandler<WebEvent<String>> createAlertHandler() {
    return stringWebEvent -> {
        AlertHandler alertHandler = new AlertHandler(
                stringWebEvent.getData(),
                event -> {
                    webView.setDisable(false);
                    removeViewOverlay();
                }
        );
        overlayView(alertHandler);

        // todo block until the user accepts the alert.
    };
}

. . .

// add an effect for disabling and enabling the view.
getView().disabledProperty().addListener(new ChangeListener<Boolean>() {
    final BoxBlur soften = new BoxBlur();
    final ColorAdjust dim = new ColorAdjust();
    {
        dim.setInput(soften);
        dim.setBrightness(-0.5);
    }

    @Override
    public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldValue, Boolean newValue) {
        if (newValue) {
            getView().setEffect(dim);
        } else {
            getView().setEffect(null);
        }
    }
});

. . . 

public class AlertHandler extends VBox {
    public AlertHandler(String message, EventHandler<ActionEvent> confirmHandler) {
        super(14);

        // add controls to the popup.
        final Label promptMessage = new Label(message);
        final ImageView alertImage = new ImageView(ResourceUtil.getImage("alert_48.png"));
        alertImage.setFitHeight(32);
        alertImage.setPreserveRatio(true);
        promptMessage.setGraphic(alertImage);
        promptMessage.setWrapText(true);
        promptMessage.setPrefWidth(350);

        // action button text setup.
        HBox buttonBar = new HBox(20);
        final Button confirmButton = new Button(getString("dialog.continue"));
        confirmButton.setDefaultButton(true);

        buttonBar.getChildren().addAll(confirmButton);

        // layout the popup.
        setPadding(new Insets(10));
        getStyleClass().add("alert-dialog");
        getChildren().addAll(promptMessage, buttonBar);

        final DropShadow dropShadow = new DropShadow();
        setEffect(dropShadow);

        // confirm and close the popup.
        confirmButton.setOnAction(confirmHandler);
    }
}

. . . 

getView().getEngine().setOnAlert(dialogFactory.createAlertHandler());

实际上,我编写上述代码的唯一原因是因为当时没有与 ControlsFX 等效的库。如果我从头开始开发一个项目,我会首先尝试使用 ControlsFX。

 类似资料:
  • 问题内容: 如何将通过javascript 函数打开的弹出窗口居中显示在屏幕变量中心,以当前选定的屏幕分辨率为中心? 问题答案: 更新:它现在也可以在尚未超出屏幕宽度和高度的窗口上运行! 如果您使用双显示器,则窗口将水平居中,而不是垂直居中…使用此功能可以解决此问题。 用法示例:

  • 问题内容: 有人可以建议我如何在Java Swing中实现弹出窗口。我希望弹出窗口是模式窗口(打开弹出窗口时用户无法返回主窗口)。 我尝试使用JDialog进行操作,但是它只允许一个小部件供用户输入,而我需要多个小部件。我在这里可能是错的,但这就是我能够做到的。 感谢你的帮助。 问题答案: 使用一个JDialog。可以添加的内容没有限制,可以将所需的内容添加到JDialog中(与使用JFrame时

  • 所以我正在c#winform中使用硒火狐web驱动程序,我在下面有这段代码来获取弹出窗口的句柄,当您单击“webtraffic_popup_start_button”时显示,它应该获得弹出窗口的句柄,但弹出句柄与当前句柄相同。 任何帮助将不胜感激 这就是弹出式菜单的样子。

  • 本文向大家介绍bootstrap modal弹出框的垂直居中,包括了bootstrap modal弹出框的垂直居中的使用技巧和注意事项,需要的朋友参考一下 本人前端菜鸟,公司项目尝试采用bootstrap,我身先士卒为同事趟“坑”,无奈UI妹子刁难非得让modal弹出框垂直居中,为了前端开发岗位的荣誉,花时间满足之。 最先就是百度咯,方法,就是修改源码 这里的that.element就是最外层的d

  • 问题内容: 我正在尝试在自举弹出窗口中显示HTML,但不知为何它不起作用。我在这里找到了一些答案,但这对我不起作用。如果我做错了事,请告诉我。 问题答案: 您不能使用,因为它属于它,所以它不起作用,请更改它,这一切都很好。 这是正在工作的 JSFiddle ,它向您展示了如何创建引导弹出窗口。 代码的相关部分如下: HTML: JavaScript: 顺便说一句,您始终至少需要启用弹出窗口。但是您

  • 本文向大家介绍jQuery实现弹出带遮罩层的居中浮动窗口效果,包括了jQuery实现弹出带遮罩层的居中浮动窗口效果的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jQuery实现弹出带遮罩层的居中浮动窗口效果。分享给大家供大家参考,具体如下: 运行效果图如下: 更多关于jQuery相关内容感兴趣的读者可查看本站专题:《jQuery扩展技巧总结》、《jQuery常用插件及用法总结》、《jQu