JavaFX:FXML:如何让孩子扩展其大小以适应父窗格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22270994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaFX: FXML: How to make the child to extend its size to fit the parent pane?
提问by Dean Chiu
I have managed to load a child fxml(sub UI) under a parent fxml (mainMenu UI). I have created an AnchorPane with id "mainContent". This pane is bound to 4 sides and changes in accords to the stage.
我设法在父 fxml(mainMenu UI)下加载了一个子 fxml(子 UI)。我创建了一个 ID 为“mainContent”的 AnchorPane。此窗格绑定到 4 个边,并根据舞台变化。
The child window will be loaded into the "mainContent" anchorpane. However, I can't figure out how to make the child to change along with its parent "mainContent".
子窗口将被加载到“mainContent”锚面板中。但是,我不知道如何让孩子与其父“mainContent”一起改变。
My child UI is called like this.
我的孩子 UI 就是这样调用的。
@FXML
private void mnuUserLevel_onClick(ActionEvent event) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("DBedit.fxml"));
loader.setController(new DBeditEntityUserlevel());
try {
Node n = (Node)loader.load();
mainContent.getChildren().add(n);
} catch (IOException e){
System.out.println(e.getMessage());
}
}
To further illustrate my question, please see my snap shot. The red square is the child. The yellow square is the "mainContent" AnchorPane of the MainMenu parent.
为了进一步说明我的问题,请参阅我的快照。红色方块是孩子。黄色方块是 MainMenu 父级的“mainContent”AnchorPane。
采纳答案by Sascha B
If you set the static
methods setTopAnchor( child, value )
, setBottomAnchor( ... )
, setLeftAnchor( ... )
, setRightAnchor( ... )
of class AnchorPane
to 0.0, the child Node
will get stretched to the full extend of the parent AnchorPane
.
如果设置static
方法setTopAnchor( child, value )
,setBottomAnchor( ... )
,setLeftAnchor( ... )
,setRightAnchor( ... )
类AnchorPane
到0.0,孩子Node
会被拉伸到全延长父AnchorPane
。
Documentation Link: AnchorPane
文档链接:AnchorPane
edit: in the documentation link you can also see how you can set these values in your java code.
编辑:在文档链接中,您还可以看到如何在 Java 代码中设置这些值。
FXML example:
FXML 示例:
<AnchorPane fx:id="mainContent" ...>
<StackPane fx:id="subPane" AnchorPane.topAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" ></StackPane>
</AnchorPane>
回答by EthanP
If you have a Region
, which is a subclassof Node
that includes Axis
, Chart
, Control
, and Pane
(this probably includes anything you might want to load), you can bindthe child's size to the space in the parent similar to how they did here. Now any future adjustments of the parent's size will be reflected in the child.
如果你有一个Region
,这是一个子类的Node
是包括Axis
,Chart
,Control
,和Pane
(这可能包括你可能想负载任何东西),你可以绑定孩子的大小类似他们是如何做家长的空间在这里。现在,未来对父级大小的任何调整都将反映在子级中。
Region n = (Region)loader.load();
mainContent.getChildren().add(n);
n.prefWidthProperty().bind(mainContent.widthProperty());
n.prefHeightProperty().bind(mainContent.heightProperty());
回答by mike_s
With the look at the structure of your interface I guess you better use BorderPane as your parent container with this suggestion don't use AnchorPane directly inside the BorderPane container here is my suggestion you do:
看看你的界面结构,我猜你最好使用 BorderPane 作为你的父容器,这个建议不要直接在 BorderPane 容器内使用 AnchorPane,这是我的建议:
->BorderPane-Top = "your menu"
->BorderPane-Top = "你的菜单"
->BorderPane-Center = another container (could be SplitPane, another BorderPane etc.. but not AnchorPane I guess but you can try if you want)
->BorderPane-Center = 另一个容器(可能是 SplitPane、另一个 BorderPane 等。但我猜不是 AnchorPane 但如果你愿意,你可以尝试)
->BorderPane-Bottom = another container (could be hbox with buttons or label for info or notifications etc..)
->BorderPane-Bottom = 另一个容器(可以是带有按钮或标签的 hbox,用于信息或通知等。)
回答by blumberk1990
You could try with setting prefWidth. I don't know why, but it seems like it takes the prefWidth which is set in SceneBuilder after referencing your newPane to your AnchorPane.
您可以尝试设置 prefWidth。我不知道为什么,但在将 newPane 引用到 AnchorPane 之后,它似乎需要在 SceneBuilder 中设置的 prefWidth。
Node newPane = FXMLLoader.load(getClass().getResource("view/YourPane.fxml"));
List<Node> parentChildren = ((Pane)yourAnchorPaneId.getParent()).getChildren();
parentChildren.set(parentChildren.indexOf(yourAnchorPaneId), newPane);
yourAnchorPaneId.setPrefWidth(1800); // 1800 just example value for test
Main.primaryStage.setWidth(500); // 500 example value with which you wishe to start app
回答by Developer
Method 1 :
方法一:
// @FXML private AnchorPane pnlContainer;
FXMLLoader loader = new FXMLLoader(getClass().getResource("Demo.fxml"));
Node _node = loader.load();
_node.prefWidth(pnlContainer.widthProperty().doubleValue());
_node.prefHeight(pnlContainer.heightProperty().doubleValue());
// container child clear
pnlContainer.getChildren().clear();
// new container add
pnlContainer.getChildren().add(_node);
Alternative method;
替代方法;
FXMLLoader loader = new FXMLLoader(getClass().getResource("Demo.fxml"));
Node _node = loader.load();
AnchorPane.setTopAnchor(_node, 0.0);
AnchorPane.setRightAnchor(_node, 0.0);
AnchorPane.setLeftAnchor(_node, 0.0);
AnchorPane.setBottomAnchor(_node, 0.0);
// container child clear
pnlContainer.getChildren().clear();
// new container add
pnlContainer.getChildren().add(_node);
Method 2 detail link : JavaFX Panel inside Panel auto resizing
方法 2 详细链接:面板内的 JavaFX 面板自动调整大小
回答by mike rodent
I don't think the accepted answer is the right one. Setting the anchors in an AnchorPane
does what it says in the documentation(setBottomAnchor
):
我不认为接受的答案是正确的。在 anAnchorPane
中设置锚点会按照文档( setBottomAnchor
)中的说明进行操作:
If set, the anchorpane will maintain the child's size and position so that its bottom is always offset by that amount from the anchorpane's bottom content edge.
如果设置,锚窗格将保持子级的大小和位置,以便其底部始终从锚窗格的底部内容边缘偏移该量。
But that's not what is desired. It is to arrange things so that the child and parent are the same size.
但这不是我们想要的。就是把东西安排得让孩子和父母的大小一样。
The important thing to appreciate, from my experiments, is that a parent Node
will accept and adapt to the width and height (preferred width? preferred height?) of its child/children... if you tell it to. In other words, the mechanism works in the contrary direction to the one you might assume: the parent can be told to adapt to the child, not the child to the parent.
根据我的实验,要领会的重要一点是,父母Node
会接受并适应其孩子/孩子的宽度和高度(首选宽度?首选高度?)...如果你告诉它。换句话说,该机制的运作方向与您可能假设的相反:可以告诉父母去适应孩子,而不是孩子去适应父母。
With an HBox
containing a ScrollPane
containing an AnchorPane
containing a TextArea
, using SceneBuilder, this does what the question is looking for:
使用HBox
包含一个ScrollPane
包含一个AnchorPane
包含一个 TextArea
,使用 SceneBuilder,这就是问题所要寻找的:
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<ScrollPane prefHeight="100.0">
<content>
<AnchorPane>
<children>
<TextArea fx:id="logTextArea" prefWidth="800.0">
</TextArea>
</children>
</AnchorPane>
</content>
</ScrollPane>
</children>
</HBox>
Note that there is no use of anchors, and above all that the ScrollPane
and the AnchorPane
have no "preferred width" setting.
请注意,没有使用锚点,最重要的是ScrollPane
和AnchorPane
没有“首选宽度”设置。
In SceneBuilder, the thing to adjust here for the ScrollPane
and the AnchorPane
is in the right-hand panel/concertina, under "Layout: ...:" choose the ScrollPane
, and set "Pref Width" to "USE_COMPUTED_AREA". Then choose the AnchorPane
and do the same. Finally, choose the TextArea
and set this to your choice, e.g. in my case 800 (pixels). Obviously this setting can be adjusted to something more sophisticated in your code if you want.
在 SceneBuilder 中,此处要调整ScrollPane
和 的AnchorPane
内容位于右侧面板/六角手风琴中,在“布局:...:”下选择ScrollPane
,并将“Pref Width”设置为“USE_COMPUTED_AREA”。然后选择AnchorPane
并执行相同的操作。最后,选择TextArea
并将其设置为您的选择,例如在我的情况下为 800(像素)。显然,如果您愿意,可以将此设置调整为代码中更复杂的内容。
You will then see that the parent Node
of the TextArea
(AnchorPane
) and grandparent Node
(ScrollPane
) adjust to accommodate the TextArea
.
然后您将看到( ) 和祖父母( )的父级Node
进行调整以适应.TextArea
AnchorPane
Node
ScrollPane
TextArea
Note that the prefWidth
setting of the HBox
then gets ignored. It is the normal job of a container like an HBox
to accommodate its descendants, and it would only be if you set its maxWidth
to something incompatible with the requirements of its descendants that that constraint would then apply.
请注意,then的prefWidth
设置将HBox
被忽略。HBox
容纳其后代是容器的正常工作,只有当您将其设置maxWidth
为与其后代的要求不兼容的内容时,该约束才会应用。
If you set a grandchild Node
like this with a prefWidth
of 800, I assume there is some way of calculating the width, under normal circumstances, of the grandparent ScrollPane
: this will be something to do with settings of borders, padding, margins and the like, in all three components involved. Note the protected
method in class Region
, computePrefWidth
, intended for subclasses to override, which may be of interest.
如果设置一个孙子Node
这样用prefWidth
的800,我认为有计算的宽度,一般情况下,祖父的一些方法ScrollPane
:这将是事做边框,填充,边距的设置等,在所有三个组件都涉及。请注意protected
class Region
, 中的方法computePrefWidth
,旨在供子类覆盖,这可能很有趣。
Plus, in the case of ScrollPane
, the presence or absence of vertical and/or horizontal scrollbars, as and when these appear. If you set wrapText
to true
on the TextArea
you might hope that a horizontal scrollbar will never appear. My experiments seem to show that you also need to set ScrollPane
's fitToWidth
Property
to true
.
另外,在 的情况ScrollPane
下,垂直和/或水平滚动条的存在与否,当它们出现时。如果您设置wrapText
为true
onTextArea
您可能希望永远不会出现水平滚动条。我的实验似乎表明您还需要将ScrollPane
's设置fitToWidth
Property
为true
.