fxmlLoader.load() will not load object hiearchy - javafx

I have 2 windows (login and main) with appropriate controllers.
I got this piece of code. This is located in LoginController.java. When I run app, it will open login window from /fxml/login.fxml where the LoginController is set with fx:controller. Then there is Sign In button. Method signIn() is asociated with this button. When i click it, it will close Login window, get controller of main window and open main window from specific fxml file (/fxml/main.fxml). Meanwhile it will get strings from Login window's text fields and pass them to the MainController (those credentials are used in execution of SQL statements).
public void signIn(ActionEvent event) {
MngApi.closeWindow(btn); //closes parent window of specified node
try{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/main.fxml"));
Parent root1 = fxmlLoader.load();
Stage stage = new Stage();
stage.setTitle("PrintED");
stage.setScene(new Scene(root1, 1058, 763));//1058, 763
MainController ctrl = fxmlLoader.getController();
ctrl.setCredentials(uName.getText(), uPasswd.getText(),
ipAddress.getText(), dbName.getText());
stage.show();
}catch (IOException e){
}
}//signIn end
Now this is the problem: When i click Sign In button, the signIn() method will execute, Login window will close and SUCCESSFUL BUILD will pop up. No other window will open. After debugging I found out that program will stop at this line (everything before is done)
Parent root1 = fxmlLoader.load();
No error, no information, only successfull build. The most mysterious thing for me is that it worked before! Login wondow got closed and main windows appeared. I only added some new methods, action events and stuff. I made no changes to LoginController and fxml file. I only made changes to MainController (added methods and action event for buttons in main.fxml).
I have no idea what's bad and i am clueless. Please help!

Okay so I found out whats wrong. The error was in initilize() method. There i put a method which should initialize columns in my TreeTableView. I thought that when i run program, initialize wil execute (after Controller constructor) and it will run code line by line. so i put there initializeColumns() method, si it will execute first and only once. Looked like this:
public void initialize(){
initializeOrdersColumns();
//this listener will load (refresh) orders automaticaly when Orders Tab is selected
tabOrders.setOnSelectionChanged((event) -> {
if (tabOrders.isSelected()) {
List<TreeItem<Order>> allOrdersList = new ArrayList<>();
stackItems(allOrdersList, root);
root = new TreeItem<>();
ttwOrders.setRoot(root);
ttwOrders.setShowRoot(false);
}
});
//When we click refresh button, orders tab will reload Orders
btnOrdersRefresh.setOnAction((event) -> {
List<TreeItem<Order>> allOrdersList = new ArrayList<>();
stackItems(allOrdersList, root);
root = new TreeItem<>();
ttwOrders.setRoot(root);
ttwOrders.setShowRoot(false);
});
}//end of initialize()
After I deleted content of initialize() method, everything went well, so it was obvious that error code is in there. Then I commented all code except first method (initializeColumns()) and program went wrong. When I commented only initializeColumns() method the program went well again. So it was clear, initializeColumns() cannot be in initialize() method. Don't know why yet, but i will find out.

Related

JavaFX correct way to open and close a Stage multiple times

Problem:
I am working on a client server desktop application using JavaFx, everything works fine except that I have found that when I open a new stage clicking a button on the Home Page, the new Stage loads data only the first time I open it. The initialize method of the new stage sends a request to server and receives back an object whose fields are loaded on the new stage. None exception is thrown, the server always send the object correctly (tested by printing its vales on console).
My suspicion is that when I click the button to open a new stage, it creates a new instance of the FXML Loader each time. What I don't get is dued to the fact that the execution cycle is always the same both the first time I open the stage and the following ones.
I finally tried to insert a button in the second window which, when clicked, loads the object on the window, and this works correctly also when I open the window multiple times, but obviously I don't like this solution, which would force the user to click the button to retreive data.
Here is the HomePage Controller method that allows to open the new stage:
#FXML
void showSecondView(MouseEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/View_FXML/generaRichiesta.fxml"));
Pane secondPageLayout = loader.load();
SecondController secCon = loader.getController();
stage = new Stage();
stage.setScene(new Scene(secondPageLayout));
stage.setTitle("Second Stage");
stage.show();
}
Here is the Initialize method for the Second Stage
public void initialize(URL url, ResourceBundle resourceBundle) {
//sending request to server and calling the following function to update the
//view withe the received object
Platform.runLater(
() -> {
//setting the view node "textField" with the object received from server
//if I print this value on console I always get the object correctly but
//it is loaded only the first time. When i call this function from a button it always
//works but I should do it manually
textField.setText().receivedObject.toString();
}
);
}
I really don't get what the problem could be, I think it may be because when I create every time and FXMLLoader object.
Any suggestions?
Thanks
I found the error, basically I'm using the Observable Pattern, every time I opened a controller, I associated the controller object in a hashmap and didn't accept other insertion of objects of the same class. Also each time I closed the second stage, I omitted to remove to remove the first instance of the controllere from the map, so the Observable Pattern sent notifications of changes only and always to the first instance of the controller created and not to the subsequent ones that were created by reopening the window

Unity - GameObject.Find() works only on server

I am making a simple networking game. The scene has a button named 'ReloadButton' and i am trying to find this button and add a listener to it through my script attached on the player.
private Button reloadBtn;
void Start()
{
GameObject tempGO = GameObject.Find("ReloadButton");
if (tempGO != null)
{
reloadBtn = tempGO.GetComponent<Button>();
reloadBtn.onClick.AddListener(weaponManager.Reload);
}
}
I am doing it this way because direct referencing of 'ReloadButton' to the script through public Buttonvariable is not possible.
The code works fine on the server, the listener is also added correctly. but on the client, the GameObject.Find("ReloadButton") throws a NullReferenceException.
Seems like the client cannot find the Button itself.
I cannot proceed further in my project without solving this problem, I hope some of you can point me towards the problem.

Passing objects between controllers without initializing the main window

I have read this post about Passing Parameters JavaFX FXML. What I want to know is. Is it possible to pass an object without reinitializing the window? Ideally, I would like to have a popup window where the user enters their login information. Then when they press the login button, the login window goes away and the login info is passed back to the main window.
Display the popup with showAndWait(), which will block execution until the window is dismissed. Then you can just call a method (that you define) on the controller to retrieve the data you need. Something like:
FXMLLoader loader = new FXMLLoader(...);
Scene scene = new Scene(loader.load());
Stage loginPopup = new Stage();
loginPopup.setScene(scene);
LoginController loginController = loader.getController();
loginPopup.showAndWait();
MyLoginData data = loginController.getLoginData();
// process data...

Show progress while loading FXML file

JavaFX application has a tree menu and clicking on a menu item loads an fxml file image attached
Some of the FXMLs are nested and are taking up to 2-3 seconds to load. I would like to show a progress indicator while FXMLs are getting loaded and initialized. Controller's initialization code can be executed as a Task and bind it's progress to a progress bar control, but the problem is that some of code needs to be executed in FX Application thread using Platform.runLater(). If I do that, there is no way to know when the initialization is completed.
Is there a way to handle this seemingly simple task ?
I cannot share the controller code which is taking long time to load, but for the purpose of this question, please assume the following initialization code is the culprit. I cannot execute this block of code in a Task thread as UI changes cannot be made from threads other than JavaFX Application thread. If I wrap the part of code that changes UI inside Platform.runLater(), task may finish it's execution even before the UI changes are completed.
public void initialize(URL url, ResourceBundle rb) {
if (webEngine == null) {
webEngine = helpView.getEngine();
}
try {
Path filepath = Paths.get("docs/index.html");
webEngine.load(filepath.toUri().toString());
} catch (Exception ex) {
Alert alert = new Alert(Alert.AlertType.WARNING, "Failed to read doc files", ButtonType.OK);
alert.show();
}
}
Raj

JavaFX - Why system.out.println doesn't work in my application

I want to get a console output in my application debugging, but wherever I put println method console doesn't print anything. For example, I want to get "Hi" after clicking the "play" button, everything except println, will invoke normally.
#FXML
protected void handlePlayButton(ActionEvent event) {
System.out.println("hi!");
filePath = cTable.getSelectionModel().getSelectedItem().getFilePath();
index = cTable.getSelectionModel().getSelectedIndex();
player = new Play();
player.player(filePath);
}
There might be an issue with where the stdout is pointing. Are you running it inside an IDE or might it have been redirected somewhere else in your code?

Resources