У меня есть объявление TabPane
следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TabPane?>
<TabPane fx:id="rootNode" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" stylesheets="@dark_theme.css" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.AppController" />
И я хочу добавить вкладки с моего контроллера. Итак, я делаю:
jsonConfig.getAvailableChannelIds().forEach( chId -> {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("tab_item.fxml"));
Tab item = fxmlLoader.load();
item.setText(String.format("%d", chId));
rootNode.getTabs().add(item);
}catch (Exception e) {
e.printStackTrace();
}
});
"tab_item.fxml" выглядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.VBox?>
<Tab xmlns:fx="http://www.w3.org/1999/XSL/Transform">
<VBox>
<fx:include source="test.fxml"/>
</VBox>
</Tab>
И, наконец, «test.fxml»:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: red;" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" />
И вот что у меня есть:
Чего мне не хватает, чтобы заполнить Tab
контент красным квадратом?
Я предполагаю, что AnchorPane
в test.fxml
нужно maxHeight
и maxWidth
установить на Infinity
.
Вы явно устанавливаете предпочтительный размер 600 x 400. Что вы ожидаете, что произойдет /
Не связано: это xmlns:fx="http://www.w3.org/1999/XSL/Transform"
не является пространством имен для FXML. Предоставленное вами пространство имен XML предназначено для XSL-преобразований, которые вообще не используются в вашем документе. Вместо этого используйте xmlns:fx="http://javafx.com/fxml"
. Пространство имен в этом случае важно только для проверки XML (которую вы не используете) и для помощи инструментам, таким как IDE, для улучшения помощи при редактировании.
@SedJ601, к сожалению, имея этот <AnchorPane maxHeight="Infinity" maxWidth="Infinity" minHeight="-Infinity" minWidth="-Infinity" style="-fx-background-color: red;" xmlns="javafx.com/javafx/19 " xmlns:fx=" javafx.com/fxml/1" /> приводит к тому, что элемент не отображается на сцене. Есть идеи?
Вы избавились от prefHeight="400.0" prefWidth="600.0"
, как предложил @James_D?
@ SedJ601 SedJ601 да, я избавился от него, но ключевым моментом здесь является наличие AnchorPane в качестве содержимого для Tab. При первоначальном использовании подхода VBox удаление prefs приводит к тому, что элемент не отображается.
Если вы также избавитесь от минимального и максимального размеров, чтобы панель привязки могла расти, вы можете затем указать VBox
, чтобы панель привязки в test.fxml
увеличивалась настолько, насколько она хочет, используя обычные настройки VBox
. Я не совсем понимаю, почему у вас вообще есть VBox
.
Итак, я нашел по крайней мере обходной путь здесь -> просто оберните fx:include с помощью AnchorsPane, и он работает:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.AnchorPane?>
<Tab xmlns:fx="http://www.w3.org/1999/XSL/Transform">
<content>
<AnchorPane>
<fx:include source="test.fxml" AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0"/>
</AnchorPane>
</content>
</Tab>
Ваше решение явно установить размер pref на то, что вам не нужно, состоит в том, чтобы найти обходной путь, который заставляет игнорировать размер pref????
@James_D, а что вы предлагаете, кроме того, что вы немного высокомерны в своем комментарии? Если я где-то ошибаюсь, не могли бы вы указать это прямо, если это возможно?
Не указывайте предпочтительный размер явно.
@James_D, как я вижу, этого недостаточно, если я останусь с VBox, я вообще ничего не увижу. Таким образом, ключевым моментом здесь является использование AnchorPane в качестве содержимого для элемента Tab.
У вас также явно установлен максимальный размер USE_PREF_SIZE
(-Infinity
). Избавьтесь от всего этого, и вы сможете использовать настройки макета естественным образом. Почему вам все равно нужно обернуть содержимое вкладки в панель?
Большинство панелей макета, таких как VBox
, по умолчанию пытаются изменить размер своего содержимого до предпочтительного размера и будут делать все возможное, чтобы размеры не превышали ограничений, указанных как минимум и максимум.
Я рекомендую прочитать старый учебник по верстке Oracle . Он был написан давным-давно (до Java 8), поэтому стиль кода немного устарел, но все концепции компоновки по-прежнему актуальны. Также прочтите Javadocs для пакета макета, и, вероятно, вы уже читали Javadocs для любого компонента макета, который вы используете (если нет, вам всегда следует читать документы для используемых вами классов).
У тебя есть
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0"
style="-fx-background-color: red;"
xmlns="http://javafx.com/javafx/19"
xmlns:fx="http://javafx.com/fxml/1" />
который явно устанавливает предпочтительный размер на 600x400 пикселей, а также устанавливает минимальный и максимальный размеры на -Infinity
, что является контрольным значением Region.USE_PREF_SIZE. Поэтому VBox
всегда будет изменять размер содержимого до 600x400 пикселей (если для этого достаточно места в VBox
).
Удалите все эти настройки (я также исправил пространство имен, хотя оно вам здесь действительно не нужно):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane style="-fx-background-color: red;"
xmlns:fx="http://javafx.com/fxml" />
Теперь VBox
по-прежнему будет пытаться установить предпочтительный размер содержимого, который по умолчанию вычисляется из собственного содержимого. Поскольку панель привязки пуста, предпочтительный размер будет вычисляться как 0x0. Однако, поскольку максимальный размер теперь не ограничен, вы можете указать VBox
, чтобы он увеличивался:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.VBox?>
<Tab xmlns:fx="http://javafx.com/fxml/">
<VBox fillWidth="true">
<fx:include source="test.fxml" VBox.vgrow="ALWAYS" />
</VBox>
</Tab>
Теперь содержимое, определенное в test.fxml
, заполнит VBox
. Поведение Tab
заключается в том, чтобы позволить его содержимому заполнить всю область вкладки, поэтому VBox
заполнит вкладку.
Конечно, не совсем понятно, почему вы вообще заворачиваете test.fxml
в VBox
. Поскольку вкладка будет заполнена своим содержимым по умолчанию, почему бы просто не упростить
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<Tab xmlns:fx="http://javafx.com/fxml/">
<fx:include source="test.fxml" />
</Tab>
Вот полный пример, в котором удалены все ненужные жестко заданные размеры и лишние панели макета:
HelloApplication.java
:
package org.jamesd.examples.tab;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
hello-view.fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TabPane?>
<TabPane fx:id="rootNode"
tabClosingPolicy="UNAVAILABLE"
xmlns:fx="http://javafx.com/fxml/"
fx:controller="org.jamesd.examples.tab.AppController" />
AppController.java
:
package org.jamesd.examples.tab;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class AppController {
@FXML
private TabPane rootNode ;
public void initialize() {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("tab_item.fxml"));
Tab item = fxmlLoader.load();
item.setText(String.format("%d", 42));
rootNode.getTabs().add(item);
}catch (Exception e) {
e.printStackTrace();
}
}
}
tab-item.fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<Tab xmlns:fx="http://javafx.com/fxml/">
<fx:include source="test.fxml" />
</Tab>
и test.fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane style="-fx-background-color: red;"/>
спасибо за подробное объяснение и ссылки на документы - теперь у меня есть картинка