I am no expert but I think there are two ways to do it.
Method 1
Wrap everything of that stage into a main FXML/controller file/class (as a View). Then you need to load that FXML file twice, once in the new stage, the other in a dedicated space you have prepared in your main stage.
The reference of both controller instances should ideally be held at the same object, either in your application class or the class hosting your main stage.
From there, you can either bind values and let the binding API do the work for you.
Example:
Main View:
public class MainView {
private Model model = new Model();
private Pane space; // Dedicated space
public void spawnView() {
FXMLLoader spawnViewLoader = new FXMLLoader(getClass().getResource("View.fxml"));
Parent spawnView = spawnViewLoader.load(); // Need to catch IOException
ViewController spawnController = spawnViewLoader.getController();
spawnController.setup(model);
new Stage(new Scene(view));
FXMLLoader dupViewLoader = new FXMLLoader(getClass().getResource("View.fxml"));
Parent dupView = dupViewLoader.load(); // Need to catch IOException
ViewController dupController = dupViewLoader.getController();
dupController.setup(model);
space.getChildren().setAll(dupView);
}
}
Model:
public class Model {
private final StringProperty title = new SimpleStringProperty();
private final StringProperty titleProperty() { return title; }
private final String getTitle() { return title.get(); }
private final void setTitle(final String title) { this.title.set(title); }
}
View controller:
public class ViewController {
@FXML private Label label;
private Model model;
public void setup(Model model) {
if (model == null)
throw new NullPointerException();
this.model = model;
label.textProperty().bind(model.titleProperty());
}
// Other stuff
}
Be careful of the binding though - I'm quite sure whatever I wrote is going to cause memory leak; both Views will not clean up as long you're holding a reference of model
. You can always do it without binding, but it's going to be more tedious to update values.
Method 2
This method is more complex and is likely to be several frames slower. I'm not going to post sample codes as this is not that straight-forward.
You need to have a reference of the Scene
of that stage, and use an AnimationTimer
to call the snapshot
method of the scene object.
Then you need to use an ImageView
in your main stage to display the snapshots returned.
Seriously, I think this method would cause the duplicate View to be several frames slower than the original's.