如何将fxml文件适合ChildAnchorPane?

时间:2021-05-18 17:05:28

I'm working on my project which is having two fxml files, i managed to open both fxml files from MainController in both ways like

我正在处理我的项目,它有两个fxml文件,我设法从两个方面打开来自MainController的两个fxml文件

Both the actions performed by clicking on Button

通过单击Button执行的操作

  1. creating and opening new stage,scene and loading fxml file.
  2. 创建和打开新的舞台,场景和加载fxml文件。

  3. replacing child AnchorPane with fxml.
  4. 用fxml替换子AnchorPane。

Problem is in second way: fxml file won't fit according to the child Anchor Pane which I've already defined in my Main FXML file with coordinates , its appears on top left corner of the primaryStage and is there any way i can fix this problem ?

问题是第二种方式:fxml文件根据我已经在我的Main FXML文件中用坐标定义的子Anchor Pane不适合,它出现在primaryStage的左上角,有什么方法我可以解决这个问题问题?

Please follow the screen shot which explains the GUI view of my application. 如何将fxml文件适合ChildAnchorPane?

请按照屏幕截图说明我的应用程序的GUI视图。

MainController.java

@FXML
private Button okay;
@FXML
private AnchorPane HostScreen,MainScreen;
class NewStage{
    NewStage() throws IOException{
        Stage subStage = new Stage();
        subStage.setTitle("Connect To MySQL Host");
        HostScreen = (AnchorPane)FXMLLoader.load(getClass().getResource("SQLHostWindow.fxml"));
        Scene HostScene = new Scene(HostScreen,640,400);
        subStage.setScene(HostScene);
        subStage.centerOnScreen();
        subStage.show();
    }
}
class NewScene{
    NewScene() throws IOException{
        HostScreen = (AnchorPane)FXMLLoader.load(getClass().getResource("SQLHostWindow.fxml"));
        MainScreen.getChildren().set(0, HostScreen);
        System.out.println(MainScreen.getChildren().get(0));
    }
}

@FXML
public void OpenHostScreen(ActionEvent event) throws IOException{

    new NewStage();
    new NewScene();

}

1 个解决方案

#1


3  

First of all it's absolute nonsense to use constructors of inner classes to modify the scene, unless those classes have some other functionality. In this case you just create objects for no real reason. Instead the functionality should be moved to methods, e.g.

首先,使用内部类的构造函数来修改场景是绝对无意义的,除非这些类具有一些其他功能。在这种情况下,您只是创建对象没有真正的原因。相反,应将功能移至方法,例如

void replaceChild() throws IOException{
    HostScreen = (AnchorPane)FXMLLoader.load(getClass().getResource("SQLHostWindow.fxml"));
    MainScreen.getChildren().set(0, HostScreen);
    System.out.println(MainScreen.getChildren().get(0));
}

@FXML
public void OpenHostScreen(ActionEvent event) throws IOException{
    replaceChild();
}

Furthermore you cannot expect the layout parameters of the original node to simply be transfered to the replacement node just because you replace the node. Panes often store layout properties inside the properties map of the child node. The contents of this map are not automatically copied.

此外,您不能仅仅因为替换节点而将原始节点的布局参数简单地转移到替换节点。窗格通常在子节点的属性映射中存储布局属性。不会自动复制此地图的内容。

Also there are some properties of the child Node that could be relevant for the parent depending on it's type and the parameters stored in the properties:

此外,子节点的某些属性可能与父节点相关,具体取决于它的类型和存储在属性中的参数:

  • layoutX, layoutY (in case they are not determined by the parent)
  • layoutX,layoutY(如果它们不是由父级确定的话)

  • managed
  • Translate, Rotate, Scale
  • 翻译,旋转,缩放

  • size
  • ...

In this case you most likely only need to copy the anchors, size and position, which can be done by copying the properties and assigning layoutX, layoutY, prefWidth and prefHeight.

在这种情况下,您很可能只需要复制锚点,大小和位置,这可以通过复制属性并分配layoutX,layoutY,prefWidth和prefHeight来完成。

Example

@Override
public void start(Stage primaryStage) {
    Region back = new Region();
    back.relocate(10, 10);
    back.setPrefSize(590, 390);
    back.setStyle("-fx-background-color: blue;");

    AnchorPane.setBottomAnchor(back, 10d);
    // AnchorPane.setTopAnchor(back, 10d);
    AnchorPane.setLeftAnchor(back, 10d);
    AnchorPane.setRightAnchor(back, 10d);

    Button btn = new Button("Change");

    AnchorPane root = new AnchorPane(back, btn);

    btn.setOnAction((ActionEvent event) -> {
        // replace first child of root with new one; keep anchors & position/size
        Region region = new Region();
        region.setStyle("-fx-background-color: red;");
        Node oldRegion = root.getChildren().set(0, region);

        // copy properties from old map
        Map<Object, Object> properties = region.getProperties();
        oldRegion.getProperties().forEach((k, v) -> properties.putIfAbsent(k, v));

        // copy position & set pref size to size of replaced node
        region.relocate(oldRegion.getLayoutX(), oldRegion.getLayoutX());
        Bounds bounds = oldRegion.getLayoutBounds();
        region.setPrefSize(bounds.getWidth(), bounds.getHeight());
    });

    Scene scene = new Scene(root, 600, 400);

    primaryStage.setScene(scene);
    primaryStage.show();
}

#1


3  

First of all it's absolute nonsense to use constructors of inner classes to modify the scene, unless those classes have some other functionality. In this case you just create objects for no real reason. Instead the functionality should be moved to methods, e.g.

首先,使用内部类的构造函数来修改场景是绝对无意义的,除非这些类具有一些其他功能。在这种情况下,您只是创建对象没有真正的原因。相反,应将功能移至方法,例如

void replaceChild() throws IOException{
    HostScreen = (AnchorPane)FXMLLoader.load(getClass().getResource("SQLHostWindow.fxml"));
    MainScreen.getChildren().set(0, HostScreen);
    System.out.println(MainScreen.getChildren().get(0));
}

@FXML
public void OpenHostScreen(ActionEvent event) throws IOException{
    replaceChild();
}

Furthermore you cannot expect the layout parameters of the original node to simply be transfered to the replacement node just because you replace the node. Panes often store layout properties inside the properties map of the child node. The contents of this map are not automatically copied.

此外,您不能仅仅因为替换节点而将原始节点的布局参数简单地转移到替换节点。窗格通常在子节点的属性映射中存储布局属性。不会自动复制此地图的内容。

Also there are some properties of the child Node that could be relevant for the parent depending on it's type and the parameters stored in the properties:

此外,子节点的某些属性可能与父节点相关,具体取决于它的类型和存储在属性中的参数:

  • layoutX, layoutY (in case they are not determined by the parent)
  • layoutX,layoutY(如果它们不是由父级确定的话)

  • managed
  • Translate, Rotate, Scale
  • 翻译,旋转,缩放

  • size
  • ...

In this case you most likely only need to copy the anchors, size and position, which can be done by copying the properties and assigning layoutX, layoutY, prefWidth and prefHeight.

在这种情况下,您很可能只需要复制锚点,大小和位置,这可以通过复制属性并分配layoutX,layoutY,prefWidth和prefHeight来完成。

Example

@Override
public void start(Stage primaryStage) {
    Region back = new Region();
    back.relocate(10, 10);
    back.setPrefSize(590, 390);
    back.setStyle("-fx-background-color: blue;");

    AnchorPane.setBottomAnchor(back, 10d);
    // AnchorPane.setTopAnchor(back, 10d);
    AnchorPane.setLeftAnchor(back, 10d);
    AnchorPane.setRightAnchor(back, 10d);

    Button btn = new Button("Change");

    AnchorPane root = new AnchorPane(back, btn);

    btn.setOnAction((ActionEvent event) -> {
        // replace first child of root with new one; keep anchors & position/size
        Region region = new Region();
        region.setStyle("-fx-background-color: red;");
        Node oldRegion = root.getChildren().set(0, region);

        // copy properties from old map
        Map<Object, Object> properties = region.getProperties();
        oldRegion.getProperties().forEach((k, v) -> properties.putIfAbsent(k, v));

        // copy position & set pref size to size of replaced node
        region.relocate(oldRegion.getLayoutX(), oldRegion.getLayoutX());
        Bounds bounds = oldRegion.getLayoutBounds();
        region.setPrefSize(bounds.getWidth(), bounds.getHeight());
    });

    Scene scene = new Scene(root, 600, 400);

    primaryStage.setScene(scene);
    primaryStage.show();
}