0

I am converting my Swing application to JavaFX. I have the core and the UI separated with Core and Window objects. What's nice is that I can create two windows and link them to the same core. Any updates in one window update the core and then update the other window:

Core core = new Core();
Window window1 = new Window(core); //Extends JFrame
Window window2 = new Window(core);

What I would like to do is keep this same idea when I convert to JavaFX. I am a new guy with JavaFX so I don't really understand it too much, especialy the Stages and Scenes. From what I can tell, the start method has a Stage object passed that I have to use. This changes my system, so to create the second Stage I need another system.

Can I create my own class that extends Stage and then pass a Core object to it?

Chris Smith
  • 2,928
  • 4
  • 27
  • 59
  • JavaFx has fxml for this sort of things. You can use scenebuilder and attach a controller, which you can use to control all of the application windows. I am not that familiar with it, but i know its in the right direction. – WonderWorld Apr 03 '15 at 22:40
  • 1
    Yes you can create a class which extends Stage and then pass a Core object to it. – ItachiUchiha Apr 04 '15 at 04:23

1 Answers1

4

I would pass the core object to a node subtype, not the Stage.

Here is an example of sharing the "core" (in this case a click counter) between nodes on separate stages (adopted from: JavaFx: Pass Value to another class and update Label text).

In the case of this sample, one stage makes changes to the core (increments the click counter). The other stage has elements bound to the core (so that when the click counter in changed by the first stage, a label in the second stage is automatically updated to reflect the new click count value).

sharedinfo

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Clicker extends Application {

    @Override
    public void start(Stage inputStage) throws Exception {
        final ClickCounter clickCounter = new ClickCounter();

        final ClickInputView  inputView  = new ClickInputView(clickCounter);
        final ClickOutputView outputView = new ClickOutputView(clickCounter);

        inputStage.setScene(new Scene(inputView));
        inputStage.show();

        Stage outputStage = new Stage();
        outputStage.initOwner(inputStage);
        outputStage.initStyle(StageStyle.UTILITY);
        outputStage.setScene(new Scene(outputView));
        outputStage.setX(inputStage.getX());
        outputStage.setY(inputStage.getY() + inputStage.getHeight());
        outputStage.show();
    }

    private class ClickCounter {
        private final ReadOnlyIntegerWrapper numClicks =
                new ReadOnlyIntegerWrapper(0);

        public int getNumClicks() {
            return numClicks.get();
        }

        public ReadOnlyIntegerProperty numClicksProperty() {
            return numClicks.getReadOnlyProperty();
        }

        public void click() {
            numClicks.set(getNumClicks() + 1);
        }
    }

    private class ClickInputView extends StackPane {
        private final Button button = new Button("Click Me!");

        public ClickInputView(ClickCounter clickCounter) {
            button.setOnAction(event -> clickCounter.click());
            setPadding(new Insets(10));

            getChildren().setAll(button);
        }
    }

    private class ClickOutputView extends StackPane {
        private final Label clickCountLabel = new Label();

        public ClickOutputView(ClickCounter clickCounter) {
            clickCountLabel.textProperty().bind(
                    Bindings.format(
                            "Clicked %d times",
                            clickCounter.numClicksProperty()
                    )
            );
            clickCountLabel.setMinWidth(150);
            clickCountLabel.setAlignment(Pos.CENTER);
            setPadding(new Insets(10));

            getChildren().setAll(clickCountLabel);
        }
    }

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

If you want to do these kind of things with FXML it gets a little bit trickier and you have to do stuff like: Passing Parameters JavaFX FXML.

Community
  • 1
  • 1
jewelsea
  • 150,031
  • 14
  • 366
  • 406