Reputation: 2022
My project has a main GUI (Stage) with some buttons: by right click on a button I would like to run another stage in another package.
Here is the project tree
newprojectx is the package with the main GUI and
togglebuttonDraw.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.isSecondaryButtonDown()){
}
}
});
is the method for right mouse click: I would like to run from this button the .fxml from fibonaccipriceretracement package.
togglebuttonDraw is in NewProjectXController class.
Any help really appreciated.
Edit: this is the .fxml I would like to run by right click
Upvotes: 0
Views: 3679
Reputation: 1760
For small FXML's the solution of Sebastian is good, but if you are experiencing a freeze when you are opening the pop-up, maybe the FXML is too big or you are loading it over the network. In this case the FXMLLoader will block your GUI, so you will need to execute the FXMLLoader in background. You can use a Service that returns the Parent for your Scene, and create the Scene an the stage once the service has been finished.
Here is a full example:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
VBox vbox = new VBox(10);
vbox.setAlignment(Pos.CENTER);
final ProgressIndicator progress = new ProgressIndicator(-1);
progress.setVisible(false);
Button button = new Button("Open fxml");
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
final Service<Parent> service = new Service<Parent>() {
@Override
protected Task<Parent> createTask() {
return new Task<Parent>() {
@Override
protected Parent call() throws Exception {
//Out of FX Thread
String fxml = "/FxmlTest.fxml";
Parent root = FXMLLoader.load(getClass().getResource(fxml));
return root;
}
};
}
};
progress.visibleProperty().bind(service.runningProperty());
service.start();
service.runningProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> value, Boolean oldValue, Boolean newValue) {
if(!newValue){//The service has ended
//In the FX Thread
Stage stage = new Stage();
Scene scene = new Scene(service.getValue());
stage.setScene(scene);
stage.show();
}
}
});
}
});
vbox.getChildren().addAll(button, progress);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I put a progress indicator to show that the service can take a time while loading.
If you want to check where it is in a FX Thread, you just need to use Platform.isFxApplicationThread().
Hope it helps.
Upvotes: 0
Reputation: 6574
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/fibonaccipriceretracement/FibonacciPriceRetracementDialog.fxml"));
Parent content = (Parent) loader.load();
Stage stage = new Stage();
stage.setScene(new Scene(content));
stage.show();
Upvotes: 2