JavaFX最大化窗口如果弹出对话框会移动

4

如果我使用以下方法创建javafx对话框:

public static void showDialog(Event event) throws IOException {
    dialogStage = new Stage();
    GridPane grid = (GridPane) Start.createLoader().load(Start.class.getResource("file.fxml").openStream());
    dialogStage.setScene(new Scene(grid));
    dialogStage.setTitle("Title");
    dialogStage.initModality(Modality.WINDOW_MODAL);
    dialogStage.initOwner(((Node) event.getSource()).getScene().getWindow());
    dialogStage.showAndWait();
}

如果窗口被最大化了,那么窗口会移动。即使我使用以下方法也是如此:

Modality.APPLICATION_MODAL

如果我将以下内容组合起来,它就能正常工作:

dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage.getOwner());

但在这种情况下,所有者窗口没有被阻止。
我希望我的对话框出现在一个最大化的窗口上,而不移动它。在对话框打开时,最大化窗口应该被阻止。我该怎么做?
另外,我正在使用Linux上的Java 8和JavaFX。
谢谢!

什么是“所有者窗口在最大化时移动”的意思?我不确定这是否适用于Linux,但我确定在Windows和Mac中,Modality.WINDOW_MODAL会阻止父窗口。请参考此处获取更多信息 - undefined
在第一个示例中,我使用Modality.WINDOW_MODAL,并且它按预期阻止了父窗口。如果父窗口没有使用整个屏幕大小(非全屏),则没有问题,但如果它使用整个屏幕大小,则父窗口在显示对话框之前会在屏幕上移动一点(向右和向下)。由于父窗口保持相同的大小,部分父窗口移出了屏幕。 - undefined
嗯,我无法在我的 MAC 上复制这种情况。您是如何调整父窗口大小以使用整个屏幕的?如果您通过设置大小来调整它,您可以尝试在父 stage 中使用 stage.setMaximized(true); - undefined
感谢您的努力!用户设置了窗口的大小,即使我在代码中将其设置为最大化也没有用。我稍后会在Windows操作系统上尝试。这可能是Linux特定的问题。 - undefined
2
这绝对是一个Linux特定的问题,因为我在Linux下使用javafxSceneBuiler 2.0时也遇到了同样的问题。一些对话框也会导致相同的行为。 - undefined
显示剩余4条评论
2个回答

0
作为Linux的解决办法,可以使用以下技巧:
  stage.setMaximized(true);
  if (PlatformUtil.isLinux()) {
    stage.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<>() {
      @Override
      public void handle(WindowEvent windowEvent) {
        stage.removeEventHandler(WindowEvent.WINDOW_SHOWN, this);
        Platform.runLater(() -> {
          var bounds = new Rectangle2D(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight());
          stage.setMaximized(false);
          stage.setX(bounds.getMinX());
          stage.setY(bounds.getMinY());
          stage.setWidth(bounds.getWidth());
          stage.setHeight(bounds.getHeight());
          stage.setMaximized(true);
        });
      }
    });
  }

0
终于我找到了在Linux上运行得相当好的另一种解决方案。它使用了一个小技巧:如果用户通过双击标题栏手动将窗口从最大化状态恢复,并再次通过双击标题栏将其最大化,这个bug就不再复现了。 为了模拟双击操作,我使用了Robot类:
stage.setMaximized(true);                                                                             
if (PlatformUtil.isLinux()) { // a workaround of a bug of modal dialogs shown on top of the stage     
  stage.setAlwaysOnTop(true);                                                                         
  stage.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<>() {                              
    @Override                                                                                         
    public void handle(WindowEvent windowEvent) {                                                     
      stage.removeEventHandler(WindowEvent.WINDOW_SHOWN, this);                                       
      new Thread(() -> {                                                                              
        doubleClick();                                                                                
        LockSupport.parkNanos(10_000_000L);                                                           
        doubleClick();                                                                                
        Platform.runLater(() -> stage.setAlwaysOnTop(false));                                         
      }).start();                                                                                     
    }                                                                                                 
                                                                                                      
    private void doubleClick() {                                                                      
      robotAction(stage, r -> r.mouseClick(MouseButton.PRIMARY));                                     
      LockSupport.parkNanos(1_000_000L);                                                              
      robotAction(stage, r -> r.mouseClick(MouseButton.PRIMARY));                                     
    }                                                                                                 
                                                                                                      
    private void robotAction(Stage stage, Consumer<Robot> action) {                                   
      var latch = new CountDownLatch(1);                                                              
      Platform.runLater(() -> {                                                                       
        try {                                                                                         
          var robot = new Robot();                                                                    
          var centerX = stage.getX() + stage.getWidth() / 2d;                                         
          robot.mouseMove(centerX, stage.getY() + 3d);                                                
          action.accept(robot);                                                                       
        } finally {                                                                                   
          latch.countDown();                                                                          
        }                                                                                             
      });                                                                                             
      try {                                                                                           
        latch.await();                                                                                
      } catch (InterruptedException e) {                                                              
        throw new IllegalStateException(e);                                                           
      }                                                                                               
    }                                                                                                 
  });                                                                                                 
}                                                                                                     
stage.show();                                                                                         

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接