Изменение размера таблицы JavaFX для соответствия окну

Я просто пытаюсь использовать JavaFX и заставляю меня входить в него, потому что он должен быть будущим. Я пытаюсь создать таблицу с 4 столбцами. Столбцы AND THE TABLE должны изменить размер, чтобы заполнить родительскую панель. Я не могу, чтобы жизнь меня заставила это работать. Я пробовал уже более 4 часов, а таблица не изменяет размер.

Вот мой файл 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>

Ответ 1

Работа с изменяемыми размерами

Размер изменяемых размеров элементов в JavaFX управляется менеджерами компоновки, в которых размещаются элементы.

Что вам нужно сделать

Для вашей конкретной проблемы вам нужно установить ограничения размера сетки GridPane для управления табличным представлением, которое вы разместили в сетке.

См. ограничения GridPane.hgrow и GridPane.vgrow, которые я добавил в TableView:

<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.

grid

Рефакторизованный образец

Я загрузил FXML в Scene Builder 2 и установил соответствующие ограничения, и он автоматически изменил размер автоматически, когда я использую функции предварительного просмотра Сценарий.

<?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 вы размещаете только один node в GridPane. Просто размещение TableView непосредственно в центре вашего BorderPane или использование более простого родителя макета, такого как StackPane, работало бы просто отлично. Но, возможно, это просто некоторая сокращенная версия более сложного пользовательского интерфейса, поэтому, возможно, именно поэтому вы использовали GridPane.

Дополнительная литература

Если у вас есть время, прочитайте макет в JavaFX в Node, Pane, Group и GridPane javadoc и попробуйте этот небольшой макет ограничивает демонстрацию.

Дополнительные вопросы для комментариев

укажите, что StackPane будет работать, но StackPanes, похоже, не имеют Hgrow и Vgrow?

StackPanes не требует ограничений Hgrow или Vgrow. Эти ограничения устанавливают Приоритеты, которые определяются как:

Перечисление, используемое для определения приоритета роста (или сокращения) данного node область расположения, когда ее область имеет больше (или меньше) пространства и несколько узлов конкурируют за это пространство.

С помощью StackPane все дочерние элементы располагаются друг над другом, они не конкурируют в пространстве, поэтому такие параметры приоритета роста для дочерних узлов не применимы.

Ответ 2

После некоторой домашней работы мы придумали некоторую квалификационную информацию о контейнерах FXML. В значительной степени по той же причине, приведенной выше @user3403469. В Scene Builder есть длинный список "контейнеров". Imho, только эти 9 элементов и Pane квалифицируются как контейнер макета, поскольку они наследуют от

< Pane > ... родительский для всех Панели классов. Хотя оба, Pane и Control наследуют от региона, только дочерние классы Pane имеют свойства макета.

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

Вы можете считать, что дочерние классы Control более или менее наследуют события и действия. Макет, подобный вещам, должен поступать из области инкапсуляции, и единственное, что имеет элементы макета для обертывания "элемента управления", - это "панель".

Эти элементы FXML будут индивидуальными менеджерами компоновки, описанными в ответе @jewelsea и в других местах.

Я думаю, что контейнеры "Control" по-прежнему являются контейнерами в FXML. Кажется, что они должны быть "внутри" панели, чтобы делать добро; -)

Исправления и комментарии приветствуются.

связаны: