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

Я просто пробую JavaFX и пробиваюсь к нему, потому что предполагается, что это будущее. Я пытаюсь создать таблицу с 4 столбцами. Столбцы И ТАБЛИЦА должны изменить размер, чтобы заполнить родительскую панель. Я не могу на всю жизнь заставить это работать. Я пытаюсь уже более 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>

person bzanchi    schedule 15.05.2014    source источник
comment
Используйте AnchorPane вместо GridPane.   -  person brian    schedule 16.05.2014


Ответы (2)


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

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

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

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

См. ограничения 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 просто отражает API Java, поэтому вы можете сделать то же самое и в исходном коде Java; то есть GridPane.setHGrow(node, priority). Однако, если вы используете FXML для своего макета, рекомендуется определить ограничения макета в FXML.

сетка

Рефакторинг образца

Я загрузил ваш FXML в Scene Builder 2 и установил соответствующие ограничения, и кажется, что он автоматически изменяет размер, когда я использую функцию предварительного просмотра 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, сработало бы просто отлично. Но, возможно, это просто урезанная версия более сложного пользовательского интерфейса, поэтому, возможно, именно поэтому вы использовали GridPane.

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

Если у вас есть время, почитайте о компоновке в JavaFX в Узел, Панель , Группа и GridPane javadoc и попробуйте этот небольшой демонстрация границ макета.

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

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

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

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

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

person jewelsea    schedule 15.05.2014
comment
@jewelsea Я не знал, что можно перетаскивать компоненты внутри области иерархии. Это очень помогает, хотелось бы, чтобы было проще научиться пользоваться SceneBuilder. - person Kyle Bridenstine; 27.09.2014
comment
Вы (или это был @will ? ) упомянули, что StackPane будет работать, но в StackPanes, похоже, нет Hgrow и Vgrow? - person Caelum; 22.10.2015

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

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

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

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

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

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

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

связанные:

person will    schedule 04.06.2014