Различные результаты привязки в Scene Builder и приложении

Я сгенерировал следующий FXML в Scene Builder. Когда я просматриваю его в Scene Builder и изменяю размер окна, внутренний разделенный вид сохраняет расстояние между собой и привязкой. Однако когда я запускаю FXML в моем приложении, это не так. Есть идеи? Я использую javafx 2.2.51.

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

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="477.0" prefWidth="515.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.nm.haze.LibraryViewController">
  <children>
    <SplitPane dividerPositions="0.09484536082474226" focusTraversable="true" prefHeight="415.0" prefWidth="487.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="48.0">
      <items>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
          <children>
            <ListView prefHeight="371.0" prefWidth="425.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
          </children>
        </AnchorPane>
      </items>
    </SplitPane>
  </children>
</AnchorPane>

И мой код контроллера:

package com.nm.haze;

import java.net.URL;
import java.util.ResourceBundle;

public class LibraryViewController extends BaseController {

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

    }
}

Основной код

private static final String LIBRARY_SELECT = "LibrarySelect";
private static final String LIBRARY_VIEW = "LibraryView";

@Override
public void start(Stage primaryStage) throws IOException {
    SceneController sceneController = new SceneController(primaryStage, new SettingsManager());
    sceneController.loadScene(LIBRARY_SELECT);
    sceneController.loadScene(LIBRARY_VIEW);
    if (sceneController.setupNeeded()) {
        sceneController.setScreen(LIBRARY_SELECT);
    } else {
        sceneController.setScreen(LIBRARY_VIEW);
    }
    Group root = new Group();
    root.getChildren().addAll(sceneController);
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
}

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

Код SceneController:

public class SceneController extends StackPane {

Map<String, Node> scenes = new HashMap<>();
Stage stage;
SettingsManager settingsManager;

public SceneController(Stage stage, SettingsManager settingsManager) {
    this.stage = stage;
    this.settingsManager = settingsManager;
}

public void addScene(String name, Node scene) {
    scenes.put(name, scene);
}

public void loadScene(String name) throws IOException {
    FXMLLoader myLoader = new FXMLLoader(getClass().getResource(name + ".fxml"));
    Parent loadScreen = (Parent)myLoader.load();
    ((BaseController)myLoader.getController()).setSceneController(this);
    addScene(name, loadScreen);
}

public void setScreen(final String name) {
    List<Node> children = getChildren();
    Node scene = scenes.get(name);
    if(scene != null) {
        if (children.size() > 0) {
            children.remove(0);
        }
        children.add(0, scene);

    } else {
        throw new IllegalArgumentException("Scene has not been loaded");
    }
}

public Stage getStage() {
    return stage;
}

public boolean setupNeeded() {
    return settingsManager.setupNeeded();
}

}

Чтобы понять, в чем проблема, посмотрите скриншоты до и после. Расстояние между ListView и AnchorPane должен остаться таким же (и в Scene Builder).

1 ответ

Решение

`Вам просто нужно зафиксировать минимальную и максимальную ширину части SplitPane, ширину которой вы не хотите изменять при изменении размера вашего окна!

Здесь я исправил левую часть, установив minWidth а также maxWidth из AnchorPane on the left side, Вы можете сделать то же самое для правой стороны, в зависимости от ваших требований.

abcFxml.fxml

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="477.0" prefWidth="515.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="bounty.LibraryViewController">
  <children>
    <SplitPane dividerPositions="0.09484536082474226" focusTraversable="true" prefHeight="415.0" prefWidth="487.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="48.0">
      <items>
        <AnchorPane minHeight="0.0" minWidth="100.0" prefHeight="160.0" prefWidth="100.0" maxHeight="160.0" maxWidth="100.0" />
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
          <children>
            <ListView prefHeight="371.0" prefWidth="425.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
          </children>
        </AnchorPane>
      </items>
    </SplitPane>
  </children>
</AnchorPane>

контроллер

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

public class LibraryViewController extends Application
{

    @Override
    public void start(Stage arg0) throws Exception {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("abcFxml.fxml"));
        AnchorPane pane = (AnchorPane) fxmlLoader.load();
        Scene scene = new Scene(pane);
        arg0.setScene(scene);
        arg0.show();

    }

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

}

Скриншоты

Size1

Размер 2

РЕДАКТИРОВАТЬ: согласно обновлению пользователя

Проблема, с которой вы сталкиваетесь, заключается в Group ты используешь. Сама группа не изменяемого размера! Попробуйте поместить StackPane непосредственно на вашу сцену (как я сделал), или вы можете использовать любой другой контейнер, например VBOX / HBOX так далее

@Override
public void start(Stage primaryStage) throws IOException {
    SceneController sceneController = new SceneController(primaryStage, new SettingsManager());
    sceneController.loadScene(LIBRARY_SELECT);
    sceneController.loadScene(LIBRARY_VIEW);
    if (sceneController.setupNeeded()) {
        sceneController.setScreen(LIBRARY_SELECT);
    } else {
        sceneController.setScreen(LIBRARY_VIEW);
    }
    primaryStage.setScene(new Scene(sceneController));
    primaryStage.show();
}

public static void main(String[] args) {
    launch(args);
}
Другие вопросы по тегам