Issue
question is simple i have created small program that have 2 stages the main and the secondary, the main window has a button to launch the secondary stage and the secondary stage has text field and button and label when i enter a text in the text field and pressed the button the text will be shown in the label , what i want to do is when i close the secondary stage and the program is still running i want the data to be same so when pressed button and launch the secondary stage again i will see the last result as if i never closed the secondary stage
here is the main class
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
private Stage primaryStage;
@Override
public void start(Stage primaryStage) throws Exception{
this.primaryStage=primaryStage;
mainWindow();
}
void mainWindow() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("FirstWindow.fxml"));
Parent root = loader.load();
Controller controller = loader.getController();
controller.setMain(this ,primaryStage);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}catch (IOException e){
e.printStackTrace();
}
}
public void secondaryWindow() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("SecondWindow.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
Stage secondaryStage=new Stage();
secondaryStage.initOwner(primaryStage);
secondaryStage.initModality(Modality.WINDOW_MODAL);
swController controller = loader.getController();
controller.setMain(this,secondaryStage);
secondaryStage.setScene(scene);
secondaryStage.show();
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
and the secondstage control class
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
/**
* Created by ahmednageeb on 11/29/16.
*/
public class swController implements Initializable {
private Main main;
private Stage secondaryStage;
public void setMain(Main main, Stage secondaryStage) {
this.main = main;
this.secondaryStage = secondaryStage;}
@FXML
private Label label;
@FXML
private TextField text;
@FXML
private void change(ActionEvent event) {
String a=text.getText();
label.setText(a);
text.clear();
}
public void goBack() {
secondaryStage.close();
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}
and finally the firststage controller
package sample;
import javafx.stage.Stage;
public class Controller {
private Main main;
private Stage primaryStage;
public void setMain(Main main,Stage primaryStage){
this.main=main;
this.primaryStage =primaryStage;
}
public void close(){
primaryStage.close();
}
public void changeWindow(){
main.secondaryWindow();
}
}
Solution
One solution could be to load the secondary window on start up but hide it. Then use the button to show it. When you close it, hide it again.
See if something like this works!
Main:
package hidepopup;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HidePopup extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("first stage");
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
First FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="hidepopup.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
First Controller:
package hidepopup;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
public class FXMLDocumentController implements Initializable {
@FXML
private Label label;
FXMLLoader loader;
Parent root2;
Stage stage2;
@FXML
private void handleButtonAction(ActionEvent event) {
try
{
Scene scene2 = new Scene(root2);
stage2.setScene(scene2);
stage2.setTitle("second stage");
stage2.showAndWait();
}
catch(IllegalArgumentException ex)
{
stage2.show();
}
}
@Override
public void initialize(URL url, ResourceBundle rb) {
try
{
loader = new FXMLLoader(getClass().getResource("FXMLPopup.fxml"));
root2 = loader.load();
FXMLPopupController dac = (FXMLPopupController) loader.getController();
stage2 = new Stage();
}
catch (IOException ex)
{
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Second FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="hidepopup.FXMLPopupController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Second Controller
package hidepopup;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
public class FXMLPopupController implements Initializable {
@FXML
public Label label;
@FXML
private void handleButtonAction(ActionEvent event){
label.getScene().getWindow().hide();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
The layout for both windows are exactly the same, so after you press the button you might want slide the top layout over. Also, I didn't test to see if the second stage held its data. Add a text box to the second stage and test it out. I hope this helps.
Answered By - SedJ601
Answer Checked By - Timothy Miller (JavaFixing Admin)