Как предотвратить изменение размера развернутого окна при загрузке нового FXML в JavaFX? [дубликат]

avatar
Dan
8 апреля 2018 в 08:30
883
1
1

Я создал SSCCE в JavaFX, чтобы продемонстрировать проблему. В нем две сцены. Размер обеих сцен и сцены 600 x 400. Каждая сцена имеет одну кнопку. Когда вы нажимаете ее, вы переходите к другой сцене. Работает нормально.

Проблема в следующем:

Если я изменю сцену, когда программа window/stage развернута, размер окна уменьшится до 600 x 400 и установится в верхнем левом углу экрана компьютера. Когда я навожу курсор на кнопку «Развернуть/Восстановить вниз», появляется надпись «Восстановить вниз». Таким образом, программа считает, что она все еще максимизирована. Но это не так. Если я нажму «Восстановить вниз», окно переместится в центр экрана компьютера после восстановления вниз.

Хотя окно развернуто, я хочу, чтобы оно оставалось таким при смене сцен. Может ли кто-нибудь показать мне, как это делается? Я новичок в JavaFX.

Здесь может быть кое-что важное. В моем файле FXML вы можете видеть, что я поместил кнопку в GridPane. GridPane находится внутри группы. И группа находится внутри StackPane. Это необходимо. Потому что я предпочитаю использовать GridPane. И я не хочу, чтобы мои кнопки textfields и т. д. перемещались при изменении размера окна/сцены. Поэтому я поместил GridPane в группу. И я хочу, чтобы сцена была в центре, когда окно развернуто. Поэтому я поместил группу внутрь StackPane.

.

У моего SSCCE два файла FXML и три класса. Один класс имеет основной метод. Два других класса являются контроллерами.

Это класс с основным методом:

package com;

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

public class Launcher extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        try {
            StackPane pane = (StackPane)FXMLLoader.load(getClass().getResource("/com/Scene1.fxml"));
            Scene viewScene = new Scene(pane, 600, 400);
            primaryStage.setScene(viewScene);
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

Класс контроллера первой сцены:

package com;

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

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Scene1Controller implements Initializable {
    @FXML
    private Label label;

    @FXML
    private TextField textField;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

    }

    public void changeScene(ActionEvent event) throws IOException {
        // Changes the scene
        StackPane pane = FXMLLoader
                .load(getClass().getResource("/com/Scene2.fxml"));
        Scene scene = new Scene(pane);
        Stage stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
        stage.setScene(scene);
        stage.show();
    }
}

Файл FXML вышеуказанного контроллера.

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.Group?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.StackPane?>

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.131" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.Scene1Controller">
   <children>
      <Group>
         <children>
            <GridPane prefHeight="400.0" prefWidth="600.0">
              <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints maxHeight="204.0" minHeight="0.0" prefHeight="0.0" vgrow="SOMETIMES" />
                <RowConstraints maxHeight="370.0" minHeight="10.0" prefHeight="370.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true" preserveRatio="true" GridPane.columnSpan="2" GridPane.rowSpan="2">
                     <GridPane.margin>
                        <Insets top="28.0" />
                     </GridPane.margin>
                  </ImageView>
                  <Button mnemonicParsing="false" onAction="#changeScene" text="Go to Scene 2" GridPane.columnSpan="2147483647" GridPane.rowIndex="1">
                     <GridPane.margin>
                        <Insets left="260.0" />
                     </GridPane.margin>
                  </Button>
               </children>
            </GridPane>
         </children>
      </Group>
   </children>
</StackPane>

Я поделился здесь только одним файлом FXML и его классом контроллера. Это потому, что другой FXML и класс контроллера в значительной степени идентичны данному FXML и контроллеру.

Во время своих поисков я наткнулся на этот вопрос здесь, где человеку посоветовали подумать о смене корня вместо сцены. Я действительно не знаю, как это делается и может ли это решить мою проблему. Мне нужен отдельный FXML и Контроллер для каждого изменения экрана для моей программы.

Большое спасибо за ваше время. Пожалуйста, дайте мне знать, если вопрос нуждается в большей ясности. Я исправлю.

Источник

Ответы (1)

avatar
Emre Dalkiran
8 апреля 2018 в 10:39
0

Вы можете попробовать ответить на этот вопрос. Этот ответ решает проблему двумя разными способами. Первый изменяет корень при загрузке новой сцены, а второе предлагаемое решение инициирует новую сцену с заданными значениями ширины и высоты.

Dan
8 апреля 2018 в 17:29
0

Спасибо. Это кажется очень многообещающим. Это работает, когда я загружаю FXML из метода запуска, а затем загружаю другой файл FXML из того же метода после задержки. Это прекрасно работает. Окно остается развернутым. Но я не знаю, как использовать код в контроллере. После получения рута я должен установить его в сцене правильно? Я не знаю, как получить к нему доступ. Попробовал создать новую сцену и поставить в ней рут. Но это не работает. Он также не генерирует никаких исключений. Я просто ничего не делаю, как будто не было инструкций, что делать.

Emre Dalkiran
8 апреля 2018 в 18:20
0

Вы можете определить в нем контроллер файла FXML с помощью команды fx:controller. См. это руководство по началу работы с FXML. Вы также можете сделать это вручную, как в этом ответе. Но я бы посоветовал вам начать JavaFX, используя руководство по началу работы и продвигаясь шаг за шагом.

Dan
8 апреля 2018 в 20:40
0

спасибо за ссылки. Я пройдусь по ним. Кроме того, я нашел ответ на свой вопрос здесь: coderhelper.com/questions/49721504/…