Возврат к primaryStage с другого контроллера

У меня есть Mainpage.fxml, и я открываю Objectpage.fxml на том же этапе. Теперь мне нужно вернуться к Mainpage.fxml через Labelpress, но у меня не получается.

Я уже пытался просто вызвать метод в своем BusinessLogic, но он должен быть статическим. Я не могу допустить, чтобы он был статичным, потому что другие части кода не будут работать.

BusinessLogic.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package softwareprojekt;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import org.json.JSONException;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import softwareprojekt.model.Event;
import softwareprojekt.model.MqttEvent;
import softwareprojekt.model.MqttObject;
import softwareprojekt.model.Subject;
import softwareprojekt.util.Parser;
import softwareprojekt.view.EventpageController;
import softwareprojekt.view.MainpageController;
import softwareprojekt.view.NewObjectDialogController;
import softwareprojekt.view.ObjectpageController;

public class BusinessLogic extends Application {

    private Stage primaryStage;
    private BorderPane rootLayout;
    private static final ObservableList<Event> eventData = FXCollections.observableArrayList();
    private static final ObservableList<Subject> subjectData = FXCollections.observableArrayList();
    private static ArrayList<MqttObject> objects = new ArrayList<MqttObject>();
    private static ArrayList<MqttEvent> events = new ArrayList<MqttEvent>();

    public BusinessLogic() {
        eventData.add(new Event("Olaf", "Olafs Zeitpunkt"));
        subjectData.add(new Subject("Peter", "Peters key", "Peters devID", "Peters appID"));
    }

    public static ObservableList<Event> getEventData() {
        return eventData;
    }

    public static ObservableList<Subject> getSubjectData() {
        return subjectData;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("OneTimeNotifier");

        initRootLayout();

        showMainpage();
    }

    public void init() throws FileNotFoundException, IOException, Exception {
        objects = KeyLoader.loadObjects("keyholder.txt");
        for (MqttObject obj : objects) {
            ClientMQTT mqttObj = new ClientMQTT();
            obj.setMqttObj(mqttObj);
            mqttObj.setAPP_ID(obj.getAppId());
            mqttObj.setKey(obj.getKey());
            mqttObj.start();
        }
    }

    public void initRootLayout() {
        try {
            FXMLLoader loader = new FXMLLoader();
            // Load root layout from fxml file.
            loader.setLocation(BusinessLogic.class.getResource("view/RootLayout.fxml"));
            rootLayout = (BorderPane) loader.load();

            // Show the scene containing the root layout.
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);

            // Give the controller access to the main app.
            // RootLayoutController controller = loader.getController();
            // controller.setBusinessLogic(this);

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

    public void showMainpage() {
        try {
            FXMLLoader loader = new FXMLLoader();
            // Load maintenance overview.
            loader.setLocation(BusinessLogic.class.getResource("view/Mainpage.fxml"));
            AnchorPane mainpage = (AnchorPane) loader.load();

            // Set maintenance overview into the center of root layout.
            rootLayout.setCenter(mainpage);

            // Give the controller access to the main app.
            MainpageController controller = loader.getController();
            controller.setBusinessLogic(this);

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

    }

    public void showEventpage() {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(BusinessLogic.class.getResource("view/Eventpage.fxml"));
            AnchorPane page = (AnchorPane) loader.load();
            primaryStage.setTitle("Eventpage");
            Scene scene = new Scene(page);
            primaryStage.setScene(scene);

            // Give the controller access to the main app.
            EventpageController controller = loader.getController();
            controller.setBusinessLogic(this);

            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public void backToMainpage() {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(BusinessLogic.class.getResource("view/Mainpage.fxml"));
            AnchorPane page = (AnchorPane) loader.load();
            primaryStage.setTitle("Mainpage");
            Scene scene = new Scene(page);
            primaryStage.setScene(scene);

            // Give the controller access to the main app.
            ObjectpageController controller = loader.getController();
            controller.setBusinessLogic(this);

            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void showObjectpage() throws IOException {

        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(BusinessLogic.class.getResource("view/Objectpage.fxml"));
            AnchorPane page = (AnchorPane) loader.load();
            primaryStage.setTitle("Objectpage");
            Scene scene = new Scene(page);
            primaryStage.setScene(scene);

            // Give the controller access to the main app.
            ObjectpageController controller = loader.getController();
            controller.setBusinessLogic(this);

            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean showSubjectEditDialog(Subject subject) {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(BusinessLogic.class.getResource("view/NewObjectDialog.fxml"));
            AnchorPane page = (AnchorPane) loader.load();

            Stage dialogStage = new Stage();
            dialogStage.setTitle("Edit subject");
            dialogStage.initModality(Modality.WINDOW_MODAL);
            dialogStage.initOwner(primaryStage);
            Scene scene = new Scene(page);
            dialogStage.setScene(scene);

            NewObjectDialogController controller = loader.getController();
            controller.setDialogStage(dialogStage);
            controller.setSubject(subject);

            dialogStage.showAndWait();

            return controller.isOkClicked();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    public Stage getPrimaryStage() {
        return primaryStage;
    }

    public static void messageArrived(String jsonResponse) throws JSONException {
        MqttEvent newEvent = Parser.parseJSON(jsonResponse, null, "status");
        if (newEvent != null) {
            events.add(newEvent);
            // updateGUI();
        }
    }

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

    public static ObservableList<MqttEvent> getEventsGUI() {
        ObservableList<MqttEvent> currList = FXCollections.observableArrayList(events);
        return currList;
    }

    public static ObservableList<MqttObject> getObjectsGUI() {
        ObservableList<MqttObject> currList = FXCollections.observableArrayList(objects);
        return currList;
    }
}

Контроллер страницы объекта:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package softwareprojekt.view;

import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import softwareprojekt.BusinessLogic;
import softwareprojekt.model.Subject;

/**
 *
 * @author Schurke
 */
public class ObjectpageController {
    
    
    
    @FXML
    private Label labelTitle;
    @FXML
    private Label labelText1;
    @FXML
    private Label labelText2;
    @FXML
    private Label labelText3;
    @FXML
    private Label labelText4;
    @FXML
    private Label labelBack;
    @FXML
    private Button buttonSub;
    @FXML
    private Button buttonUnsub;
    @FXML
    private Button buttonRefresh;
    @FXML
    private TableView<Subject> subjectTable;
    @FXML
    private TableColumn<Subject, String> column1;
    @FXML
    private TableColumn<Subject, String> column2;
    
    private BusinessLogic businessLogic;
    
    @FXML
    private void initialize(){
        // Initialize the object table with the two columns.
        column1.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        column2.setCellValueFactory(cellData -> cellData.getValue().keyProperty());
        
        // Listen for selection changes and show the object details when changed.
        subjectTable.getSelectionModel().selectedItemProperty().addListener(
                (observable, oldValue, newValue) -> showSubjectDetails(newValue));
    }
    
    public void setBusinessLogic(BusinessLogic businessLogic){
        this.businessLogic = businessLogic;
        
        subjectTable.setItems(BusinessLogic.getSubjectData());
    }
    
    @FXML
    private void handleButtonSub(){
        Subject tempSubject = new Subject();
        boolean okClicked = businessLogic.showSubjectEditDialog(tempSubject);
        if (okClicked){
            BusinessLogic.getSubjectData().add(tempSubject);
        }
    
    }
    @FXML
    private void handleButtonEdit(){
        Subject selectedSubject = subjectTable.getSelectionModel().getSelectedItem();
        if (selectedSubject != null){
            boolean okClicked = businessLogic.showSubjectEditDialog(selectedSubject);
            if (okClicked){
                showSubjectDetails(selectedSubject);
            }
        } else {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.initOwner(businessLogic.getPrimaryStage());
            alert.setTitle("No Selection");
            alert.setHeaderText("No Subject selected");
            alert.setContentText("Please select a subject.");
            
            alert.showAndWait();
        }
    }
    
    @FXML
    private void handleButtonUnsub() {
        int selectedIndex = subjectTable.getSelectionModel().getSelectedIndex();
        if (selectedIndex >= 0){
            subjectTable.getItems().remove(selectedIndex);
        } else {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.initOwner(businessLogic.getPrimaryStage());
            alert.setTitle("No Selection");
            alert.setHeaderText("No Subject selected");
            alert.setContentText("Please select a subject.");
            
            alert.showAndWait();
        }
    }
    @FXML
    private void handleButtonRefresh() {
        
    }
    @FXML
    private void backActionHandler(){
        Stage stage = (Stage) labelBack.getScene().getWindow();
        stage.close();

        
    }

    private void showSubjectDetails(Subject subject) {
        if (subject != null) {
            labelText1.setText(subject.getName());
            labelText2.setText(subject.getKey());
            labelText3.setText(subject.getDevID());
            labelText4.setText(subject.getAppID());
        } else {
            labelText1.setText("");
            labelText2.setText("");
            labelText3.setText("");
            labelText4.setText("");
        }
    }
}

Я только что вернулся к закрытию окна. Но backActionHandler должен открыть Mainpage.fxml

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
188
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы пытались вместо этого использовать StackPane? Просто настройте StackPane, содержащую ваши панели, и покажите/скройте или переместите на задний/передний план нужную панель. Нет необходимости перезагружать один и тот же FXML несколько раз.

Дополнительный плюс: состояние вашего главного окна не теряется после того, как вы переключились на страницу объекта и обратно.

Вот пример использования StackPane для переключения компонентов пользовательского интерфейса с использованием нескольких FXML и включений.

top.fxml - определение панели стека и включение фактических представлений:

<?xml version = "1.0" encoding = "UTF-8"?>
<?import javafx.scene.layout.StackPane?>

<StackPane xmlns:fx = "http://javafx.com/fxml" fx:controller = "de.reinhardt.playground.javafx.TopController">
    <fx:include fx:id = "main" source = "main.fxml"/>
    <fx:include fx:id = "object" source = "object.fxml" />
</StackPane>

TopController.java - реализация переключения между представлениями с использованием импортированных контроллеров

public class TopController implements Initializable {
    @FXML
    private MainController mainController;
    @FXML
    private ObjectController objectController;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        mainController.setTopController(this);
        objectController.setTopController(this);
        showMainPage();
    }

    public void showMainPage() {
        objectController.hidePage();
        mainController.showPage();
    }

    public void showObjectPage() {
        mainController.hidePage();
        objectController.showPage();
    }
}

main.fxml - реализация основного вида, включая кнопку перехода к просмотру объекта

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

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>

<VBox xmlns:fx = "http://javafx.com/fxml" fx:id = "mainPage" fx:controller = "de.reinhardt.playground.javafx.MainController">
  <Label>Your Main Components go here.</Label>
  <Button onAction = "#toObjectPage">To Object Page</Button>
</VBox>

MainController -- контроллер для основного вида

public class MainController {
    private TopController topController;
    @FXML
    private Node mainPage;

    public void showPage() {
        mainPage.setVisible(true);
        mainPage.toFront();
    }

    public void hidePage() {
        mainPage.setVisible(false);
    }

    public void setTopController(TopController topController) {
        this.topController = topController;
    }

    @FXML
    public void toObjectPage() {
        topController.showObjectPage();
    }
}

object.fxml определение вида объекта и соответствующий ObjectController опущен. Они похожи на main.fxml и MainController. Единственная разница в том, что кнопка возвращает к основному виду.

Не могли бы вы уточнить, как это сделать? в гугле ничего не нахожу. Мне просто нужно переключить «основной этап» с BorderPane на StackPane? Я нашел, как добавлять кнопки и прочее, но не как добавлять целые документы FXML.

Schurke 19.05.2019 14:48

@Schurke Я добавил пример в свой ответ. Идея состоит в том, чтобы иметь три файла fxml с соответствующими контроллерами: один для основного представления, один для представления объектов и один для включения их обоих и управления видимостью и так далее.

Jochen Reinhardt 20.05.2019 11:20

Другие вопросы по теме