本文介绍了JavaFX - BorderPane / StackPane在子项更改后未调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JavaFX BorderPane中添加和删除内容时,我遇到了调整大小问题。在手动调整窗口大小之前,不会调整BorderPane内容的大小。我写了一个小测试应用程序来模拟这种行为。该应用程序构建一个BorderPane,其中包含嵌入BorderPane中心的StackPane中的矩形。在BorderPane的底部有一个包含文本和分隔符的VBox和HBox。有一个菜单项可以从BorderPane的底部删除内容(MoveText - > Right),并将类似的内容添加到BorderPane的正确位置。

I am having a resize issue when content is added and removed from a JavaFX BorderPane. The BorderPane content is not being resized until the window is manually resized. I have written a small test app to model this behavior. The application builds a BorderPane that contains a rectangle embedded within a StackPane at the center of the BorderPane. Along the bottom of the BorderPane there is a VBox and HBox that contain text and a separator. There is a menu item that removes the content from the bottom of the BorderPane (MoveText -> Right) and adds similar content to the right position of the BorderPane.

当文本被添加到BorderPane的右侧位置,矩形与文本重叠。换句话说,BorderPane中心的内容与BorderPane右边的内容重叠。

When the text is added to the right position of the BorderPane, the rectangle overlaps the text. In otherwords the content of the BorderPane center is overlapping the content in the BorderPane right.

我看到以下链接 -

调用requestLayout似乎没有帮助。我也尝试在图中的各个节点上调用impl_updatePG和impl_transformsChanged。我从这个帖子中得到了这个想法 -

I saw the following link - https://stackoverflow.com/questions/5302197/javafx-bug-is-there-a-way-to-force-repaint-this-is-not-a-single-threading-pr Calling requestLayout does not seem to help. I have also tried calling impl_updatePG and impl_transformsChanged on various nodes in the graph. I got this idea from this thread - https://forums.oracle.com/forums/thread.jspa?threadID=2242083

public class BorderPaneExample extends Application
{
   private BorderPane root;
   private StackPane centerPane;

   @Override
   public void start(Stage primaryStage) throws Exception
   {
      root = new BorderPane();
      root.setTop(getMenu());
      root.setBottom(getBottomVBox());
      centerPane = getCenterPane();
      root.setCenter(centerPane);

      Scene scene = new Scene(root, 900, 500);
      primaryStage.setTitle("BorderPane Example");
      primaryStage.setScene(scene);
      primaryStage.show();
   }

   private MenuBar getMenu()
   {
      MenuBar menuBar = new MenuBar();

      MenuItem rightMenuItem = new MenuItem("Right");
      rightMenuItem.setOnAction(new EventHandler<ActionEvent>() {
         @Override
         public void handle(ActionEvent actionEvent) {
            root.setRight(getRightHBox());
            root.setBottom(null);
            root.requestLayout();
         }
      });
      MenuItem bottomMenuItem = new MenuItem("Bottom");
      bottomMenuItem.setOnAction(new EventHandler<ActionEvent>() {
         @Override
         public void handle(ActionEvent actionEvent) {
            root.setRight(null);
            root.setBottom(getBottomVBox());
         }
      });

      Menu menu = new Menu("Move text");
      menu.getItems().add(rightMenuItem);
      menu.getItems().add(bottomMenuItem);
      menuBar.getMenus().addAll(menu);

      return menuBar;
   }

   private HBox getRightHBox()
   {
      HBox hbox = new HBox();

      VBox vbox = new VBox(50);
      vbox.setPadding(new Insets(0, 20, 0, 20));
      vbox.setAlignment(Pos.CENTER);

      vbox.getChildren().addAll(new Text("Additional Info 1"),
        new Text("Additional Info 2"), new Text("Additional Info 3"));
      hbox.getChildren().addAll(new Separator(Orientation.VERTICAL), vbox); 

      return hbox;
   }

   private VBox getBottomVBox()
   {
      VBox vbox = new VBox();

      HBox hbox = new HBox(20);
      hbox.setPadding(new Insets(5));
      hbox.setAlignment(Pos.CENTER);

      hbox.getChildren().addAll(new Text("Footer Item 1")
            , new Text("Footer Item 2"), new Text("Footer Item 3"));
      vbox.getChildren().addAll(new Separator(), hbox);

      return vbox;
   }

   private StackPane getCenterPane()
   {
      StackPane stackPane = new StackPane();
      stackPane.setAlignment(Pos.CENTER);

      final Rectangle rec = new Rectangle(200, 200);
      rec.setFill(Color.DODGERBLUE);
      rec.widthProperty().bind(stackPane.widthProperty().subtract(50));
      rec.heightProperty().bind(stackPane.heightProperty().subtract(50));

      stackPane.getChildren().addAll(rec);

      return stackPane;
   }

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

任何建议都将不胜感激。
谢谢

Any suggestions would be appreciated.Thanks

推荐答案

为了得到答案:

StackPane 需要设置其最小大小才能进行裁剪。因此,如果您明确地将 stackPane.setMinSize(0,0); 添加到 getCenterPane()方法,它应该修复你的问题。

The StackPane needs to have its minimum size set in order to do clipping. So if you explicitly add stackPane.setMinSize(0, 0); to the getCenterPane() method, it should fix your problem.

所以你的 getCenterPane()方法现在看起来像这样:

So your getCenterPane() method would now look like this:

private StackPane getCenterPane()
{
  StackPane stackPane = new StackPane();
  stackPane.setMinSize(0, 0);
  stackPane.setAlignment(Pos.CENTER);

  final Rectangle rec = new Rectangle(200, 200);
  rec.setFill(Color.DODGERBLUE);
  rec.widthProperty().bind(stackPane.widthProperty().subtract(50));
  rec.heightProperty().bind(stackPane.heightProperty().subtract(50));

  stackPane.getChildren().addAll(rec);

  return stackPane;
}

这篇关于JavaFX - BorderPane / StackPane在子项更改后未调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 23:38