英文:
How can I make an element in Javafx not overlap with another when resizing the window?
问题
我正在使用Java制作一个简单的UI应用程序。我有一个ListView和一个位于其下的ProgressBar。当首次运行应用程序时,UI正常,但当我调整窗口大小时,ListView会按照应该的方式扩展,但被ProgressBar遮挡,后者保持在顶部的原始位置固定,并在底部伸展开来。
是否有一种方法可以使ListView和ProgressBar在调整窗口大小时按比例缩放?
我尝试在这两个元素之间添加一个容器,并将其设置为始终垂直增长,但也没有奏效。
main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.learning.javaui.Controller">
<MenuBar VBox.vgrow="NEVER">
<Menu mnemonicParsing="false" text="File">
<MenuItem fx:id="quitMenuItem" mnemonicParsing="false" text="Quit" />
</Menu>
</MenuBar>
<AnchorPane VBox.vgrow="ALWAYS">
<SplitPane dividerPositions="0.3322884012539185" layoutX="77.0" layoutY="79.0" prefHeight="160.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
<GridPane layoutX="20.0" layoutY="10.0" prefHeight="30.0" prefWidth="189.0" AnchorPane.leftAnchor="15.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="5.0">
<columnConstraints>
<ColumnConstraints hgrow="NEVER" minWidth="50.0" prefWidth="100.0" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<TextField fx:id="nameField" prefHeight="25.0" promptText="Enter Name" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" />
<Button fx:id="saveButton" mnemonicParsing="false" text="Save" GridPane.columnIndex="2" GridPane.halignment="CENTER" />
</GridPane>
<ListView fx:id="names" layoutX="10.0" layoutY="43.0" prefHeight="330.0" prefWidth="200.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="40.0" />
<ProgressBar prefHeight="25.0" prefWidth="160.0" AnchorPane.bottomAnchor="20.0" AnchorPane.leftAnchor="25.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="530.0" />
</AnchorPane>
<TabPane fx:id="userPanel" prefHeight="200.0" prefWidth="200.0" />
</SplitPane>
</AnchorPane>
</VBox>
截图:
应用程序首次运行时:
应该的外观
当我调整窗口大小时,元素重叠:
调整窗口大小后的元素
英文:
I am making a simple UI app on Java. I have a Listview and a progressbar underneath it. When you first run the application the UI is fine but when I resize the window the listview expands the way it should but gets masked by progressbar which stays fixed at its original point at the top and stretches out at the bottom.
Is there a way to make it so that the listview and progressbar scale up / down in proportion when the window is being resized?
I tried adding a container in between the two elements and set it to always grow vertically but it did not work either.
main.fxml
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.learning.javaui.Controller">
<MenuBar VBox.vgrow="NEVER">
<Menu mnemonicParsing="false" text="File">
<MenuItem fx:id="quitMenuItem" mnemonicParsing="false" text="Quit" />
</Menu>
</MenuBar>
<AnchorPane VBox.vgrow="ALWAYS">
<SplitPane dividerPositions="0.3322884012539185" layoutX="77.0" layoutY="79.0" prefHeight="160.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
<GridPane layoutX="20.0" layoutY="10.0" prefHeight="30.0" prefWidth="189.0" AnchorPane.leftAnchor="15.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="5.0">
<columnConstraints>
<ColumnConstraints hgrow="NEVER" minWidth="50.0" prefWidth="100.0" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<TextField fx:id="nameField" prefHeight="25.0" promptText="Enter Name" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" />
<Button fx:id="saveButton" mnemonicParsing="false" text="Save" GridPane.columnIndex="2" GridPane.halignment="CENTER" />
</GridPane>
<ListView fx:id="names" layoutX="10.0" layoutY="43.0" prefHeight="330.0" prefWidth="200.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="40.0" />
<ProgressBar prefHeight="25.0" prefWidth="160.0" AnchorPane.bottomAnchor="20.0" AnchorPane.leftAnchor="25.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="530.0" />
</AnchorPane>
<TabPane fx:id="userPanel" prefHeight="200.0" prefWidth="200.0" />
</SplitPane>
</AnchorPane>
</VBox>
<!-- end snippet -->
Screenshots:
When app is run initially:
How it should look
When I resize the window the elements overlap:
Elements after window is resized
答案1
得分: 0
在以下代码中删除 AnchorPane.topAnchor="530.0"
:
<ProgressBar prefHeight="25.0" prefWidth="160.0" AnchorPane.bottomAnchor="20.0" AnchorPane.leftAnchor="25.0" AnchorPane.rightAnchor="20.0" />
英文:
remove AnchorPane.topAnchor="530.0"
in:
<ProgressBar prefHeight="25.0" prefWidth="160.0" AnchorPane.bottomAnchor="20.0" AnchorPane.leftAnchor="25.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="530.0" />
答案2
得分: 0
如James所述,AnchorPane
在这种情况下不建议使用。我个人更喜欢在我的布局中主要使用VBox
和HBox
。当需要将节点堆叠或并排放置时,它们非常有用。只有当需要将节点堆叠和并排放置时,我才会使用GridPane
。以下是示例代码:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="500.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.learning.javaui.Controller">
<MenuBar VBox.vgrow="NEVER">
<Menu mnemonicParsing="false" text="File">
<MenuItem fx:id="quitMenuItem" mnemonicParsing="false" text="Quit" />
</Menu>
</MenuBar>
<SplitPane dividerPositions="0.3322884012539185" prefHeight="160.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity">
<children>
<HBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" spacing="20.0">
<children>
<TextField fx:id="nameField" maxHeight="-Infinity" maxWidth="-Infinity" prefWidth="100.0" promptText="Enter Name">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</TextField>
<Button fx:id="saveButton" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" text="Save" />
</children>
<VBox.margin>
<Insets bottom="5.0" top="10.0" />
</VBox.margin>
</HBox>
<ListView fx:id="names" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets left="5.0" right="5.0" />
</VBox.margin>
</ListView>
<ProgressBar progress="0.0">
<VBox.margin>
<Insets top="2.0" />
</VBox.margin>
</ProgressBar>
</children>
</VBox>
<TabPane fx:id="userPanel" prefHeight="200.0" prefWidth="200.0" />
</SplitPane>
</VBox>
希望对你有所帮助!
英文:
As James stated, AnchorPane
is not recommended in this situation. I personally like to use VBox
and HBox
mainly in my layouts. They are very useful when nodes need to be stacked or side by side. I would use GridPane
, if and only if, nodes needed to be stacked and side by side. Example code below.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="500.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.learning.javaui.Controller">
<MenuBar VBox.vgrow="NEVER">
<Menu mnemonicParsing="false" text="File">
<MenuItem fx:id="quitMenuItem" mnemonicParsing="false" text="Quit" />
</Menu>
</MenuBar>
<SplitPane dividerPositions="0.3322884012539185" prefHeight="160.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity">
<children>
<HBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" spacing="20.0">
<children>
<TextField fx:id="nameField" maxHeight="-Infinity" maxWidth="-Infinity" prefWidth="100.0" promptText="Enter Name">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</TextField>
<Button fx:id="saveButton" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" text="Save" />
</children>
<VBox.margin>
<Insets bottom="5.0" top="10.0" />
</VBox.margin>
</HBox>
<ListView fx:id="names" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets left="5.0" right="5.0" />
</VBox.margin>
</ListView>
<ProgressBar progress="0.0">
<VBox.margin>
<Insets top="2.0" />
</VBox.margin>
</ProgressBar>
</children>
</VBox>
<TabPane fx:id="userPanel" prefHeight="200.0" prefWidth="200.0" />
</SplitPane>
</VBox>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论