繁体   English   中英

将所有阶段都带到前面

[英]Bring all Stages to the front

在我的应用程序中,我有几个独立(非模态)阶段。

我想要以下行为:

  • 当主舞台最小化时,所有其他阶段应最小化
  • 当主舞台未被最小化时,所有其他阶段应该是未最小化的
  • 当选择任何阶段时,如果某些其他阶段不可见(例如隐藏在其他应用程序后面),则应将它们带到前面

前两个要求很简单(除非我遗漏了一些东西),例如:

mainStage.iconifiedProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue != null && newValue != oldValue) {
        for (Stage s : otherStages) { s.setIconified(newValue); }
    }
});

但是我坚持第三个。 我已经尝试使用focusedProperty但它不起作用(例如,如果我点击其中一个阶段的菜单,因为它首先将其他阶段带到前面,它会失去焦点而菜单无法打开).. 。

//do this for each stage
stage.focusedProperty().addListener((observable, oldValue, newValue) -> {
    if (Boolean.TRUE.equals(newValue) && newValue != oldValue) {
        for (Stage s : otherStages) {
            s.setIconified(false);
            s.toFront();
        }
        //request the focus back, but that creates issues
        stage.requestFocus();
    }
});

关于如何实施第三项要求的任何想法?

使用stage.initOwner(parentStage)

示例应用程序

这是一个快速测试应用程序,它将所有创建阶段的所有者初始化为主应用程序阶段。

测试应用程序似乎满足您的所有要求(在Windows 7,JavaFX 8b122上测试)。

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class LotsaStages extends Application {
    private static final Color[] STAGE_COLORS = { 
        Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW 
    };
    private static final double  STAGE_OFFSET = 50;

    @Override
    public void start(Stage primaryStage) throws Exception {
        addContent(primaryStage, Color.LIGHTBLUE);
        primaryStage.show();

        double offset = STAGE_OFFSET;
        for (Color color: STAGE_COLORS) {
            Stage child = new Stage();
            child.initOwner(primaryStage);
            child.initStyle(StageStyle.UTILITY);

            child.setX(primaryStage.getX() + offset);
            child.setY(primaryStage.getY() + offset);

            addContent(child, color);

            child.show();

            offset += STAGE_OFFSET;
        }
    }

    private void addContent(Stage child, Color color) {
        child.setScene(
            new Scene(
                new Group(
                    new Rectangle(150, 70, color)
                )
            )
        );
    }

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

测试应用程序非常简单,我没有尝试复制基于菜单的问题,因此我不确定它是否会正确传递基于菜单的处理或您可能具有的其他要求。

其他问题

所以基本上initOwner将孩子们“链接”到主舞台?

是的, MSDN解释了Windows在Windows上的工作原理 在其他平台上行为可能略有不同(这就是JavaFX Javadoc在此问题上故意模糊的原因),但我认为大多数原则都是相同的,它应该适用于OS X和Linux的方式类似。

来自MSDN:

为了允许您在子窗口和父窗口之间创建关系,Window支持所有权的概念。 当窗口的所有者属性(拥有的窗口)设置为引用另一个窗口(所有者窗口)时,建立所有权。

建立此关系后,将展示以下行为:

  • 如果所有者窗口最小化,则其所有拥有的窗口也会最小化。
  • 如果拥有的窗口最小化,则其所有者不会最小化。
  • 如果所有者窗口最大化,则还原所有者窗口及其拥有的窗口。
  • 所有者窗口永远不能覆盖拥有的窗口。
  • 使用ShowDialog未打开的拥有窗口不是模态的。 用户仍然可以与所有者窗口进行交互。
  • 如果关闭所有者窗口,其拥有的窗口也将关闭。
  • 如果所有者窗口由其所有者窗口使用Show打开,并且所有者窗口关闭,则不会引发拥有窗口的Closing事件。

通过调用ShowDialog打开子窗口时,还应设置子窗口的Owner属性。 如果不这样做,那么您的用户将无法通过按任务栏按钮来恢复子窗口和父窗口。 相反,按任务栏按钮将生成一个窗口列表,包括子窗口和父窗口,供他们选择; 仅恢复选定的窗口。


这可以与孩子一起工作,如child = new Stage(UNDECORATED); child.initModality(Modality.NONE); child = new Stage(UNDECORATED); child.initModality(Modality.NONE);

是的,它确实。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM