So here is the problem I am having: I have 3 button, when I press one of the 3 buttons the new scene will display. Yet I cant seem to figure out how to make different panes appear visible depending on which button is pressed. what is the best method to perform this action? How do i use Id's from different scene controllers in order to change the properties of the pane within the main scene button listener?
currently on my main controller when each button is released the below action listener executes and displays secondscreen.fxml. the secondscreen.fxml has 2 different panes, depending on which button is pressed I need 1 of the 2 pains to set to visable.
#FXML
public void handleButtonAction(MouseEvent event) {
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("secondscreen.fxml"));
Stage stage = new Stage();
stage.setTitle("title");
stage.setScene(new Scene(root));
stage.show();
((Node)(event.getSource())).getScene().getWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
After you load a view, you can access its controler.
Keep in mind, that your controller must be asigned to your fxml file fx:controller="your.package.SecondScreenController.java"
FXMLLoader loader = new FXMLLoader.load(getClass().getResource("secondscreen.fxml"));
// load view
Parent root = loader.load();
// after view is loaded, access its controller
SecondScreenController controller = (SecondScreenController) loader.getController();
// modify view using methods on your controller
controller.setTabIndex(0)
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();
Related
Hello I am having an JavaFX app with few controllers and I have 2 options to get back to previous screen. User can click button 'leave' or after finishing some tasks on this screen will be moved to previous automatically. I have problem here because I've created method wiut fxml annotation which takes ActionEvent object as parameter and is called when user click button and when user will finish tasks and should be moved automatically to previous screen I cannot call this method because I dont this object, it's created when an action - click in this case is made. How can I make it possible for both 'exit' options?
So here is my method which is used 'onAction' for my button:
#FXML
private void leaveRoomAction(ActionEvent event) {
try {
removePlayerFromRoom();
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("LobbyView.fxml"));
Parent root = (Parent) loader.load();
LobbyController lobbyController = (LobbyController)loader.getController();
lobbyController.setClientThread(client);
lobbyController.setNameAndBalance(client.getPlayer().getName());
Scene scene = new Scene(root);
Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
And later in other part of programe:
if(isFinished()){
//here I want write leaving this screen and getting back to previous
}
First, find another way to get a reference to the Stage. Since you almost certainly have a reference to some node in the scene in your controller, you can replace
Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
with
Stage stage = (Stage) anyNode.getScene().getWindow();
where anyNode is just something you have injected into the controller.
Now you don't need the parameter at all, so you can just remove it. I.e. you end up with
#FXML
private Node anyNode ; // probably a more specific type than Node.
#FXML
private void leaveRoomAction() {
try {
removePlayerFromRoom();
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("LobbyView.fxml"));
Parent root = (Parent) loader.load();
LobbyController lobbyController = (LobbyController)loader.getController();
lobbyController.setClientThread(client);
lobbyController.setNameAndBalance(client.getPlayer().getName());
Scene scene = new Scene(root);
Stage stage = anyNode.getScene().getWindow();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
And now you can just call the method:
if ( isFinished() ) {
leaveRoomAction()
}
i have 2 fxml files, LayoutGUI.fxml (main window) and LayoutError.fxml (just a window with 2 textarea's and a ok button). Both have the same controller. I would like to show an occured exception in the LayoutError.fxml. But if i use the setText("") methods of the textareas in the controller i get a NullPointerException. If i set the text in the button clicked action in the controller, there is no exception.
public void showError(String headline,String errorTxt,String stackTrace)
{
Parent root;
try {
root = FXMLLoader.load(getClass().getClassLoader().getResource("application/view/LayoutError.fxml"));
Stage stage = new Stage();
stage.setTitle("Error Message!");
stage.setScene(new Scene(root, 450,300));
stage.show();
error_txtarea_Stacktrace.setText(stackTrace);
error_txtarea_error.setText(errorTxt);
} catch (IOException e) {
e.printStackTrace();
}
}
If i set text here there is no exception. Is it posible that the components not initialized at this time or why can i set the text in the button clicked method and not if i show the window?
#FXML
public void errorButtonOKAction(ActionEvent event)
{
// get a handle to the stage and close it
//Stage stage = (Stage) error_btnOK.getScene().getWindow();
//stage.close();
error_txtarea_Stacktrace.setText("dasds");
error_txtarea_error.setText("dsds");
}
Controller is defined in the error.fxml and the textarea's have Id's.
I'm creating a new modal dialog from the main controller class. How do I set some textfield values in the dialog before it is displayed?
URL url = getClass().getResource("SeedNodeForm.fxml");
Stage stage = new Stage();
stage.setTitle("Seed Node Information");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(((Node) event.getSource()).getScene().getWindow());
stage.initStyle(StageStyle.UTILITY);
Parent root = FXMLLoader.load(url);
stage.setScene(new Scene(root));
stage.centerOnScreen();
textfield1.setValue("foo!");
textfield2.setValue("foo2");
stage.showAndWait();
Thank you Uluk Biy - your link led me to the answer which is:
// get the controller from the loader
SeedNodeFormController c = (SeedNodeFormController) fxmlLoader.getController();
// call setter in controller routine to set needed values
c.setSeedNode(value);
I have a stage with these properties
stage = new Stage(StageStyle.DECORATED);
stage.setFullScreen(true);
stage.setFullScreenExitHint("");
stage.setTitle("My App");
stage.getIcons().add(new Image(icon-address));
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("start.fxml"));
fxmlLoader.setController(this);
...
...//and other properties
It is in full screen in this stage. I have a button and each time I click on it , a method of another class is called and the reference of this stage is passed to it.
For example, if I have two classes Start and ButtonClicked
In Start, I have this :
Button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
buttonClicked a = new buttonClicked ();
try {
a.render(stage);
} catch (Exception ex) {
Logger.getLogger(menuController.class.getName())
.log(Level.SEVERE, null , ex);
}
}
});
Now, the render method is called and I have the following code inside render :
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("buttonclicked.fxml"));
fxmlLoader.setController(this);//set Controller for our fxml file
loader = fxmlLoader.load();//loader is a stackPane because buttonclick.fxml has stackPane
stage.setScene(new Scene(loader));
stage.setFullScreen(true);
...
The problem is, if user clicks on button, stage become a 1024x700(because i have pictures in start.fxml and buttonclicked.fxml. The size of both the picture is 1024x700
After a moment, it becomes full screen. How can i fix this ?
I want to kill the delay in full screen
Thanks
Try
stage.getScene().setRoot(loader);
in render method.
By doing this, the creation of a new scene is eliminated. Therefore I guess, some UI related updates and calculations that must be done after the scene has been shown, are also eliminated.
I can't figure out how to create a modal window in JavaFX. Basically I have file chooser and I want to ask the user a question when they select a file. I need this information in order to parse the file, so the execution needs to wait for the answer.
I've seen this question but I've not been able to find out how to implement this behavior.
In my opinion this is not good solution, because parent window is all time active.
For example if You want open window as modal after click button...
private void clickShow(ActionEvent event) {
Stage stage = new Stage();
Parent root = FXMLLoader.load(
YourClassController.class.getResource("YourClass.fxml"));
stage.setScene(new Scene(root));
stage.setTitle("My modal window");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(
((Node)event.getSource()).getScene().getWindow() );
stage.show();
}
Now Your new window is REALY modal - parent is block.
also You can use
Modality.APPLICATION_MODAL
Here is link to a solution I created earlier for modal dialogs in JavaFX 2.1
The solution creates a modal stage on top of the current stage and takes action on the dialog results via event handlers for the dialog controls.
JavaFX 8+
The prior linked solution uses a dated event handler approach to take action after a dialog was dismissed. That approach was valid for pre-JavaFX 2.2 implementations. For JavaFX 8+ there is no need for event handers, instead, use the new Stage showAndWait() method. For example:
Stage dialog = new Stage();
// populate dialog with controls.
...
dialog.initOwner(parentStage);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.showAndWait();
// process result of dialog operation.
...
Note that, in order for things to work as expected, it is important to initialize the owner of the Stage and to initialize the modality of the Stage to either WINDOW_MODAL or APPLICATION_MODAL.
There are some high quality standard UI dialogs in JavaFX 8 and ControlsFX, if they fit your requirements, I advise using those rather than developing your own. Those in-built JavaFX Dialog and Alert classes also have initOwner and initModality and showAndWait methods, so that you can set the modality for them as you wish (note that, by default, the in-built dialogs are application modal).
You can create application like my sample. This is only single file JavaFX application.
public class JavaFXApplication1 extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Stage stage;
stage = new Stage();
final SwingNode swingNode = new SwingNode();
createSwingContent(swingNode);
StackPane pane = new StackPane();
pane.getChildren().add(swingNode);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Swing in JavaFX");
stage.setScene(new Scene(pane, 250, 150));
stage.show();
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private void createSwingContent(final SwingNode swingNode) {
SwingUtilities.invokeLater(() -> {
try {
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
JasperDesign jasperDesign = JRXmlLoader.load(s + "/src/reports/report1.jrxml");
String query = "SELECT * FROM `accounttype`";
JRDesignQuery jrquery = new JRDesignQuery();
jrquery.setText(query);
jasperDesign.setQuery(jrquery);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint JasperPrint = JasperFillManager.fillReport(jasperReport, null, c);
//JRViewer viewer = new JRViewer(JasperPrint);
swingNode.setContent(new JRViewer(JasperPrint));
} catch (JRException ex) {
Logger.getLogger(AccountTypeController.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}