Панель JavaFX внутри панели автоматического изменения размера

У меня есть приложение JavaFX, в котором есть только один файл FXML. В этом файле у меня есть одна AnchorPane, внутри которой есть StackPane. Вот скриншот:

моя панель внутри приложения панели

Когда я запускаю это приложение, я хочу автоматически изменять размер StackPane с помощью AnchorPane. Таким образом; StackPane автоматически получит текущую доступную ширину и высоту. В момент, когда я изменяю размер приложения, размер AnchorPane изменяется автоматически, но StackPane остается с его фиксированным размером.

Как я могу автоматически изменить размер StackPane и полностью растянуть его внутри родительской панели?

Мой код

Main.java

package app;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

  public static void main(String[] args) {
      Application.launch(args);
  }

  @Override
  public void start(Stage stage) throws Exception {
      Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
      Scene scene = new Scene(root,800,600);
      scene.getStylesheets().add(this.getClass().getResource("/app/style1.css").toExternalForm());
      stage.setScene(scene);
      stage.show();
  }
}

MainController.java

package app;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;

public class MainController implements Initializable {

   @FXML
   private AnchorPane anchorPane;
   @FXML
   private StackPane stackPane;

   @Override
   public void initialize(URL url, ResourceBundle rb) {
     stackPane.setPrefSize(anchorPane.getPrefWidth(), anchorPane.getPrefHeight()); //didn't work
   }    
}

Main.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.*?>

<AnchorPane fx:id="anchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="app.MainController">
    <StackPane fx:id="stackPane" ></StackPane>
</AnchorPane>

style1.css

#anchorPane { 
    -fx-border-width: 2px;
    -fx-border-color: chartreuse;
}
#stackPane {
    -fx-border-width: 2px;
    -fx-border-color: red;

    /* didn't work */
   -fx-hgap: 100%;
   -fx-vgap: 100%;
}

person Korki Korkig    schedule 05.03.2013    source источник


Ответы (6)


После нескольких часов поиска и тестирования, наконец, получил его сразу после публикации вопроса!

Вы можете использовать команды fxml «AnchorPane.topAnchor, AnchorPane.bottomAnchor, AnchorPane.leftAnchor, AnchorPane.rightAnchor» со значением «0.0», чтобы подогнать / растянуть / выровнять дочерние элементы внутри AnchorPane. Итак, эти команды говорят дочернему элементу следовать за своим родителем при изменении размера.

Мой обновленный код Main.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.*?>

<AnchorPane fx:id="anchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="app.MainController">
    <!--<StackPane fx:id="stackPane" ></StackPane>--> <!-- replace with the following -->
    <StackPane fx:id="stackPane" AnchorPane.topAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" ></StackPane>
</AnchorPane>

Вот результат:

введите описание изображения здесь

Документация по api: http://docs.oracle.com/javafx/2/api/javafx/scene/layout/AnchorPane.html

person Korki Korkig    schedule 05.03.2013
comment
Вы можете принять этот ответ. Позволит нам узнать, что есть решение этого вопроса. Хорошие выводы, хотя искал это. - person blo0p3r; 05.03.2013
comment
@ blo0p3r Я буду, но пока система говорит, что вы можете принять свой ответ через 2 дня;) Надеюсь, появятся другие предложения. - person Korki Korkig; 05.03.2013
comment
Привет. как добавляется кнопка. Например. ‹AnchorPane fx: id = mainContent ...› ‹StackPane fx: id = subPane AnchorPane.topAnchor = 0.0 AnchorPane.bottomAnchor = 0.0 AnchorPane.leftAnchor = 0.0 AnchorPane.rightAnchor = 0.0› Кнопка fx: id = макет кнопки X = 172.0 layoutY = 195.0 onAction = # ingresarLogin prefHeight = 35.0 prefWidth = 87.0 text = Ingresar / ›‹/StackPane› ‹/AnchorPane› правильно ?? спасибо - person Marco R; 09.02.2015
comment
Это также работает с другими элементами управления, а не только с панелями. Я просто использовал это на TabbedPane, AnchorPane и TreeView, и все они растягиваются, чтобы соответствовать. Очень полезно. - person Andrew Grothe; 27.05.2015
comment
Почему вы держите StackPane внутри AnchorPane, если вы хотите, чтобы якоря были равны 0? - person cubuspl42; 06.03.2017
comment
@ cubuspl42 представьте, что вы хотите разместить внизу (внутри зеленого) что-то вроде кнопки, и вы все еще хотите, чтобы панель (красная) тянулась вдоль пустых пространств .... Я не помню, почему именно, но это было полезно и все же я думаю. - person Korki Korkig; 22.03.2017

Я разрабатывал графический интерфейс в SceneBuilder, пытаясь адаптировать основной контейнер к любому размеру окна. Он всегда должен быть на 100% шириной.

Здесь вы можете установить эти значения в SceneBuilder:

Ограничения AnchorPane в SceneBuilder

Переключение пунктирных / красных линий фактически просто добавит / удалит атрибуты, которые Корки опубликовал в своем решении (AnchorPane.topAnchor и т. Д.).

person Ginchen    schedule 18.11.2013
comment
Какой код FXML это генерирует? Я бы хотел это увидеть. - person Andrew S; 22.03.2016
comment
ну как насчет того, чтобы запустить SceneBuilder и убедиться в этом сам ... это делается буквально менее чем за 20 секунд ... - person specializt; 11.05.2016

Также см. здесь

@FXML
private void mnuUserLevel_onClick(ActionEvent event) {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("DBedit.fxml"));
    loader.setController(new DBeditEntityUserlevel());

    try {
           Node n = (Node)loader.load();
           AnchorPane.setTopAnchor(n, 0.0);
           AnchorPane.setRightAnchor(n, 0.0);
           AnchorPane.setLeftAnchor(n, 0.0);
           AnchorPane.setBottomAnchor(n, 0.0);
           mainContent.getChildren().setAll(n);
    } catch (IOException e){
           System.out.println(e.getMessage());
    }
}

Сценарий заключается в загрузке дочернего fxml в родительский AnchorPane. Чтобы дочерний элемент растягивался в соответствии со своим родителем, используйте команду AnChorPane.setxxxAnchor.

person Dean Chiu    schedule 09.03.2014

Не нужно уступать.

просто выберите панель, щелкните правой кнопкой мыши, затем выберите По размеру родительского.

Он автоматически изменит размер панели в соответствии с размером панели привязки.

person Paragfalle    schedule 14.11.2017

Это довольно просто, потому что вы используете FXMLBuilder.

Просто выполните следующие простые шаги:

  1. Откройте файл FXML в FXMLBuilder.
  2. Выберите панель стека.
  3. Откройте вкладку Layout [левая вкладка FXMLBuilder].
  4. Задайте значение сторон, по которому вы хотите вычислить размер панели во время изменения размера рабочей области, например TOP, LEFT, RIGHT, BOTTOM.
person Sandeep Kumar    schedule 14.10.2014

Если вы используете Scene Builder, вы увидите справа панель аккордеона, которая обычно имеет три параметра («Свойства», «Макет» и «Код»). Во втором («Макет») вы увидите параметр «Ограничения [родительский макет]» (в вашем случае «Ограничения AnchorPane»).

Вы должны поставить «0» с четырех сторон элемента, который представляет родительский макет.

person Fran Pastor    schedule 18.12.2014