【问题标题】:JavaFX tableview resize to fit windowJavaFX tableview 调整大小以适应窗口
【发布时间】:2014-07-04 11:12:51
【问题描述】:

我只是在尝试 JavaFX,并且正在强行进入它,因为它被认为是未来。我正在尝试创建一个包含 4 列的表。列 AND THE TABLE 应调整大小以填充父窗格。我一辈子都无法让它发挥作用。我已经尝试了 4 个多小时,但 tableview 没有调整大小。

这是我的 FXML 文件。

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.collections.*?>
<?import t.cubed.fxml.*?>


<BorderPane styleClass="root" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="t.cubed.fxml.FXMLDocumentController">
    <top>
        <MenuBar fx:id="menuBar" styleClass="menu-bar">
        <menus>
            <Menu text="File">
                <items>
                    <MenuItem onAction="#handleOpenAction" text="Open" />
                    <MenuItem onAction="#handleExitAction" text="Exit" />
                </items>
            </Menu>
            <Menu text="Edit">
                <items>
                    <MenuItem onAction="#handleWeightAction" text="Edit Weights" />  
                    <MenuItem onAction="#handleFilterAction" text="Edit Filters" />
                    <MenuItem onAction="#handleOptionsAction" text="Options" />
                </items>
            </Menu>
        </menus>
    </MenuBar>
    </top>
    <center>
        <GridPane>
               <!--
               <padding>
                   <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> 
               </padding>
               -->
               <TableView fx:id="testTable" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="1">
                   <columnResizePolicy>
                       <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
                   </columnResizePolicy>
                   <columns>
                       <TableColumn text="TEST NUMBER">
                       <cellValueFactory>
                           <PropertyValueFactory property="testNumber" />
                       </cellValueFactory>
                       </TableColumn>
                       <TableColumn text="TEST NAME">
                           <cellValueFactory>
                           <PropertyValueFactory property="testName" />
                       </cellValueFactory>
                       </TableColumn>
                       <TableColumn text="TEST TIME(ms)">
                           <cellValueFactory>
                           <PropertyValueFactory property="testTime" />
                       </cellValueFactory>
                       </TableColumn>
                       <TableColumn text="BEST MATCH">
                           <cellValueFactory>
                           <PropertyValueFactory property="bestMatch" />
                       </cellValueFactory>
                       </TableColumn>
                   </columns>
                   <items>
                    <!--
                    <FXCollections fx:factory="observableArrayList">
                        <TestTableModel testNumber="100" testName="Test1234" testTime="0.34" bestMatch="99"/>
                    </FXCollections>
                    -->
                </items>
               </TableView>
        </GridPane>
    </center>
<stylesheets>
    <URL value="@t-cubed.css" />
</stylesheets>
</BorderPane>

【问题讨论】:

  • 使用 AnchorPane 代替 GridPane。

标签: javafx tableview fxml borderpane gridpane


【解决方案1】:

可调整大小布局的工作原理

JavaFX 中可调整大小的项目的大小由放置项目的布局管理器管理。

你需要做什么

对于您的特定问题,您需要设置 GridPane 大小约束来管理您放置在网格中的 TableView。

查看我在 TableView 上添加的 GridPane.hgrowGridPane.vgrow 约束:

<TableView fx:id="testTable" 
           GridPane.columnIndex="0" 
           GridPane.columnSpan="1" 
           GridPane.hgrow="ALWAYS" 
           GridPane.vgrow="ALWAYS"
           GridPane.rowIndex="0">

FXML 只是反映 Java API,所以你也可以在 Java 源代码中做同样的事情;即GridPane.setHGrow(node, priority)。不过,如果您在布局中使用 FXML,建议在 FXML 中定义布局约束。

重构示例

我在Scene Builder 2 中加载了您的 FXML 并设置了适当的约束,当我使用 Scene Builder 的预览功能时,它似乎可以自动调整大小。

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.collections.*?>
<?import t.cubed.fxml.*?>

<BorderPane styleClass="root" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="t.cubed.fxml.FXMLDocumentController">
  <top>
    <MenuBar fx:id="menuBar" styleClass="menu-bar">
      <menus>
        <Menu text="File">
          <items>
            <MenuItem onAction="#handleOpenAction" text="Open" />
            <MenuItem onAction="#handleExitAction" text="Exit" />
          </items>
        </Menu>
        <Menu text="Edit">
          <items>
            <MenuItem onAction="#handleWeightAction" text="Edit Weights" />
            <MenuItem onAction="#handleFilterAction" text="Edit Filters" />
            <MenuItem onAction="#handleOptionsAction" text="Options" />
          </items>
        </Menu>
      </menus>
    </MenuBar>
  </top>
  <center>
    <GridPane>
       <children>
         <!--
         <padding>
             <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
         </padding>
         -->
         <TableView fx:id="testTable" GridPane.columnIndex="0" GridPane.columnSpan="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0" GridPane.vgrow="ALWAYS">
           <columnResizePolicy>
             <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
           </columnResizePolicy>
           <columns>
             <TableColumn text="TEST NUMBER">
               <cellValueFactory>
                 <PropertyValueFactory property="testNumber" />
               </cellValueFactory>
             </TableColumn>
             <TableColumn text="TEST NAME">
               <cellValueFactory>
                 <PropertyValueFactory property="testName" />
               </cellValueFactory>
             </TableColumn>
             <TableColumn text="TEST TIME(ms)">
               <cellValueFactory>
                 <PropertyValueFactory property="testTime" />
               </cellValueFactory>
             </TableColumn>
             <TableColumn text="BEST MATCH">
               <cellValueFactory>
                 <PropertyValueFactory property="bestMatch" />
               </cellValueFactory>
             </TableColumn>
           </columns>
           <items>
          <!--
          <FXCollections fx:factory="observableArrayList">
              <TestTableModel testNumber="100" testName="Test1234" testTime="0.34" bestMatch="99"/>
          </FXCollections>
          -->
        </items>
         </TableView>
       </children>
         <columnConstraints>
            <ColumnConstraints />
         </columnConstraints>
         <rowConstraints>
            <RowConstraints />
         </rowConstraints>
    </GridPane>
  </center>
  <stylesheets>
    <URL value="@t-cubed.css" />
  </stylesheets>
</BorderPane>

一些建议

您将 TableView 放置在 GridPane 中。在您的情况下使用 GridPane 有点奇怪,因为 GridPane 您只在 GridPane 中放置一个节点。只需将 TableView 直接放在 BorderPane 的中心或使用更简单的布局父级(例如 StackPane)就可以了。但也许这只是更复杂 UI 的简化版本,所以也许这就是您使用 GridPane 的原因。

进一步阅读

如果您有时间,请阅读 NodePaneGroupGridPane javadoc 中的 JavaFX 布局,也可以试试这个小 layout bounds demo

评论的其他问题

提到 StackPane 可以工作,但 StackPanes 似乎没有 Hgrow 和 Vgrow?

StackPanes 不需要 Hgrow 或 Vgrow 约束。那些约束集Priorities,定义为:

用于确定给定的增长(或收缩)优先级的枚举 当其区域有更多(或更少)可用空间时节点的布局区域 并且多个节点正在争夺该空间。

使用 StackPane 时,所有子节点都相互叠加,它们不竞争空间,因此子节点的此类增长优先级设置不适用。

【讨论】:

  • @jewelsea 我没有意识到您可以在层次结构区域内拖放组件。这很有帮助,我希望学习如何使用 SceneBuilder 更容易。
  • 您(或者是 @will ?)提到 StackPane 可以工作,但 StackPanes 似乎没有 Hgrow 和 Vgrow?
【解决方案2】:

经过一番功课,我们想出了一些关于 FXML 容器的合格信息。与@user3403469 上面给出的原因几乎相同。在 Scene Builder 中,有一长串“容器”。恕我直言,只有这 9 个元素和 Pane 有资格作为布局容器,因为它们继承自

Pane> ...所有Pane classes的父级。虽然 Pane 和 Control 都从 Region 继承,但只有 Pane 子类具有布局属性。

* <AnchorPane>
* <BorderPane>
* <FlowPane>
* <GridPane>
* <StackPane>
* <TextFlow>
* <TilePane>
* <HBox>
* <VBox> 

您可以认为 Control 子类或多或少地继承了事件和动作。布局之类的东西需要来自封装区域,并且唯一具有可用于包装“控件”的布局元素是 - 一个“窗格”。

这些 FXML 元素将是@jewelsea 的答案和其他地方描述的定制“布局管理器”。

我猜“控制”容器仍然是 FXML 中的容器。看来他们需要在小组“内部”才能做好事;-)

欢迎指正和评论

相关

【讨论】:

    猜你喜欢
    • 2020-06-07
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 2010-12-12
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    相关资源
    最近更新 更多