JavaFX TreeView Does not Appear within Sub FXML Pane - java

I'm new to JavaFX and trying build a simple client application that has a root landing stage (rootLayout) with buttons that will allow me to swap out the RootLayout.FXML with a sub FXML. My issue begins when I attempt to load a TreeView within the sub FXML pane. The TreeView is used to load a file directory within this area of the sub-pane.
Thank you!!!
Main
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class MainApp extends Application {
public static Properties configProp;
private Stage primaryStage;
private static BorderPane rootLayout;
/**
* Just a root getter for the controller to use
*/
public static BorderPane getRoot() {
return rootLayout;
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
initRootLayout();
}
public static void main(String[] args) {
configProp = loadProperties();
launch(args);
}
/***
* Initialize the root layout
* #param args
*/
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
RootLayoutController
import java.io.IOException;
import einMyQueue.MainApp;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.BorderPane;
public class RootLayoutController {
// Reference to the main application
private MainApp mainApp;
/**
* Is called by the main application to give a reference back to itself.
*
* #param mainApp
*/
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
}
/**
* Selects the FAST Scene
*/
#FXML
private void handleFASTSceneSelection() {
try {
SplitPane paneOne = FXMLLoader.load(getClass().getResource("FASTMessageRequest.fxml"));
BorderPane border = MainApp.getRoot();
border.setCenter(paneOne);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sub-Controller that implements TextView
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import einMyQueue.MainApp;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.stage.DirectoryChooser;
public class FASTMessageRequestController {
private MainApp mainApp;
// FXML Annotations
#FXML private TreeView<String> msgDirTreeView;
#FXML private TextArea msgBodyTextArea;
#FXML private TextArea consoleTextArea;
public void initialize() {
// Using a Tree View
msgDirTreeView = new TreeView<String>();
DirectoryChooser dirChooser = new DirectoryChooser();
URL url = getClass().getResource("../resources/templates");
try {
dirChooser.setInitialDirectory(new File(url.toURI()));
File file = dirChooser.getInitialDirectory();
msgDirTreeView.setRoot(getNodesForDirectory(file));
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public TreeItem<String> getNodesForDirectory(File directory) {
TreeItem<String> msgDirRoot = new TreeItem<String>(directory.getName());
for(File iFile : directory.listFiles()) {
System.out.println("Loading " + iFile.getName());
if(iFile.isDirectory()) {
msgDirRoot.getChildren().add(getNodesForDirectory(iFile));
} else {
msgDirRoot.getChildren().add(new TreeItem<String>(iFile.getName()));
}
}
return msgDirRoot;
}
/***
* Name: setMainApp
* Purpose: Is called by the main application to give a reference back to itself.
*
* #param mainApp
*/
public void setMainApp(MainApp mainApp) {
// Is called by the main application to give a reference back to itself.
this.mainApp = mainApp;
}
}

Related

LinkedList erased in Action Handelers methods in JavaFX

I am working on an App that simulates an online shop for my Data Structures course, I am currently using JavaFX in the Eclipse IDE and Scene Builder for the GUI design, however I am trying to use a Double LinkedList to store the Accounts in the Sign In UI window, but for some reason every time that I try to insert a new Account object (in the Action Event method) into my List it doesn't inserts it, at least if I try to print it´s toString gives me a Null pointer Exception, but if the insert and the println is in the start method works. Last year a did an MP3 player using JavaFX but in Netbeans and I didn't use Scene Builder and the List did work, some one has any idea why is this happening?
package com.javafx.quvbi.controller;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.scene.input.MouseEvent;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
public class interfazController extends Application {
#FXML
private Button pausa, CreateAccBttn, LoginBttn;
#FXML
private TextField NameTF, AccountTF, PasswordTF, CardTF;
//Data
ListaDobleEnlazada<Account> accList;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
// TODO Auto-generated method stub
//NameTF = new TextField();
//AccountTF = new TextField();
//PasswordTF= new TextField();
//CardTF = new TextField();
accList = new ListaDobleEnlazada<Account>();
//accList.insertarInicio(new Account("Diego","Qubi","22f24rf2",123321));
Parent root = FXMLLoader.load(getClass().getResource("/view/OptionUI.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
System.out.println(accList.toString());
}
public ListaDobleEnlazada<Account> getAccounts() {
return accList;
}
#FXML
public void controlMusica(ActionEvent event) {
System.out.println("musica");
System.out.println(getAccounts().getInicio().toString());
}
public void CreateAccClick(MouseEvent event) throws IOException {
if(!NameTF.getText().isEmpty() && !AccountTF.getText().isEmpty() && !PasswordTF.getText().isEmpty() && !CardTF.getText().isEmpty()) {
accList.insertarInicio(new Account(NameTF.getText(), AccountTF.getText(), PasswordTF.getText(), Integer.parseInt(CardTF.getText())));
}
}
#SuppressWarnings("restriction")
public void createAccount(ActionEvent event) throws IOException {
if(!NameTF.getText().isEmpty() && !AccountTF.getText().isEmpty() && !PasswordTF.getText().isEmpty() && !CardTF.getText().isEmpty()) {
Parent loginUI = FXMLLoader.load(getClass().getResource("/view/GUI2.fxml"));
Scene logInScene = new Scene(loginUI);
Stage window = (Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(logInScene);
window.show();
System.out.println(NameTF.getText());
System.out.println(AccountTF.getText());
System.out.println(PasswordTF.getText());
System.out.println(CardTF.getText());
//this.accList.insertarInicio(new Account(NameTF.getText(), AccountTF.getText(), PasswordTF.getText(), Integer.parseInt(CardTF.getText())));
}
}
public void loginAccount(ActionEvent event) throws IOException {
Parent loginUI = FXMLLoader.load(getClass().getResource("/view/GUI2.fxml"));
Scene logInScene = new Scene(loginUI);
Stage window = (Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(logInScene);
window.show();
}
}

Managing different JavaFX stages through a signle slass

I'm writing a simple JavaFX application that has three Stages: Login, Register (Anmeldung) and Welcome (Anwendung). Sorry for the German namings!
I have created each Stage and it's Scene in an App class and the handling events in a Controller class and the designs in fxml files. I need to implement a MainApp class which has to manage the communication between Login, Anmeldung and Anwendung windows.
The MainApp should initially launch a Login window and then in there if the checkbox is selected, the MainApp should be notified and order the launch of Anmeldung window. After successful registration, the MainApp should close the Anmeldung window and show the Login window again. There, when user logs in, the MainApp should again close the Login window and order a launch for Anwendung window.
I have done the transition between Login and Anmeldung windows by modifying the LoginController, which shouldn't be done there and has to be accomplished via the MainApp.
Additionally the task wants the whole thing to be done with only one launch(args).
LoginController.java:
package controller;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Modality;
import javafx.stage.Stage;
import resources.Benutzer;
public class LoginController {
// private static MainApp mainApp;
#FXML
public TextField textFieldUserId;
#FXML
public PasswordField passwordFieldPasswort;
#FXML
public CheckBox checkBoxNeuAnmeldung;
#FXML
public Button buttonEinloggen;
private boolean neuAnmeldung = false;
// public void setCallBack(MainApp mainApp) {
// LoginController.mainApp = mainApp;
// }
#FXML
public void handleButtonEinloggenAction(ActionEvent event) throws Exception {
// Stage stage = (Stage) buttonEinloggen.getScene().getWindow();
if (neuAnmeldung == false) {
Benutzer benutzer = new Benutzer(textFieldUserId.getText(),
passwordFieldPasswort.getText());
Parent anwendungsScene = FXMLLoader
.load(getClass().getResource("/design/Anwendung.fxml"));
Stage anwendungsStage = new Stage();
((Node) (event.getSource())).getScene().getWindow().hide();
anwendungsStage.setScene(new Scene(anwendungsScene));
anwendungsStage.setTitle("Anmeldung");
anwendungsStage.show();
System.out.println(benutzer);
}
// stage.close();
System.out.println("Eingeloggt!");
}
#FXML
public void handleCheckBoxNeuAnmeldungAction(ActionEvent event)
throws Exception {
if (checkBoxNeuAnmeldung.isSelected()) {
neuAnmeldung = true;
Parent anmeldungsScene = FXMLLoader
.load(getClass().getResource("/design/Anmeldung.fxml"));
Stage anmeldungsStage = new Stage();
anmeldungsStage.initModality(Modality.WINDOW_MODAL);
anmeldungsStage
.initOwner(((Node) (event.getSource())).getScene().getWindow());
anmeldungsStage.setScene(new Scene(anmeldungsScene));
anmeldungsStage.setTitle("Anmeldung");
anmeldungsStage.show();
} else
neuAnmeldung = false;
System.out.println("Neu-Anmeldung? " + neuAnmeldung);
}
}
AnmeldungsController.java:
package controller;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import resources.Benutzer;
public class AnmeldungsController {
// private static MainApp mainApp;
#FXML
public TextField textFieldUserId;
#FXML
public PasswordField passwordFieldPasswort;
#FXML
public PasswordField passwordFieldWiederholung;
#FXML
public Button buttonAnmelden;
// public void setCallBack(MainApp mainApp) {
// AnmeldungsController.mainApp = mainApp;
// }
#FXML
public void handleButtonAnmeldenAction(ActionEvent event) {
Stage stage = (Stage) buttonAnmelden.getScene().getWindow();
if (passwordFieldPasswort.getText()
.equals(passwordFieldWiederholung.getText())) {
Benutzer benutzer = new Benutzer(textFieldUserId.getText(),
passwordFieldPasswort.getText());
System.out.println(benutzer);
System.out.println("Angemeldet!");
stage.close();
} else {
textFieldUserId.setText("Passwörter stimmen nicht überein!");
System.out.println("Passwörter stimmen nicht überein!");
System.out.println(passwordFieldPasswort.getText() + " != "
+ passwordFieldWiederholung.getText());
}
}
}
AnwendungsController.java:
package controller;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class AnwendungsController {
// private static MainApp mainApp;
#FXML
public Button buttonSchliessen;
// public void setCallBack(MainApp mainApp) {
// AnwendungsController.mainApp = mainApp;
// }
#FXML
public void handleButtonAbbrechenAction(ActionEvent event) {
Stage stage = (Stage) buttonSchliessen.getScene().getWindow();
stage.close();
System.out.println("Fenster Geschlossen!");
}
}
MainApp.java:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MainApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(
getClass().getResource("/design/Login.fxml"));
Parent root = loader.load();
primaryStage.setTitle("Benutzerverwaltung");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
Of course the other aspects of the program like Exceptions and creating/reading/deleting users etc is out of the scope of this question!
Here is the basic idea that should get you started:
public class LoginController {
private final ReadOnlyBooleanWrapper loggedIn = new ReadOnlyBooleanWrapper();
public ReadOnlyBooleanProperty loggedInProperty() {
return loggedIn.getReadOnlyProperty() ;
}
public final boolean isLoggedIn() {
return loggedInProperty().get();
}
#FXML
public TextField textFieldUserId;
#FXML
public PasswordField passwordFieldPasswort;
#FXML
public CheckBox checkBoxNeuAnmeldung;
#FXML
public Button buttonEinloggen;
private boolean neuAnmeldung = false;
#FXML
public void handleButtonEinloggenAction(ActionEvent event) throws Exception {
// assuming you verify the login credentials...
loggedIn.set(true);
System.out.println("Eingeloggt!");
}
}
and now in your MainApp you can do:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MainApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(
getClass().getResource("/design/Login.fxml"));
Parent root = loader.load();
LoginController loginController = loader.getController();
loginController.loggedInProperty().addListener((obs, wasLoggedIn, isNowLoggedIn) -> {
if (isNowLoggedIn) {
// user is now logged in, show welcome screen...
}
});
primaryStage.setTitle("Benutzerverwaltung");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}

JavaFX proper use of stages and stage controllers (bad start)

I have spent the last couple of days looking into this and trying my hand at some different solutions found but Im still having a hard time implementing them correctly.
I have a project that's bound to turn into something mid-sized so I want to make sure I am using MVC correctly from the start instead of just hacking it apart "making it work".
As of now the application will only open 3 scenes, 2 on start(no fxml needed) and another for settings(using a FXML). I do need to be careful of strong references to these as this application will be running on low resource devices.
Ultimately my questions are:
Am I using scenes and controllers correctly? and given the way I have initiated the settings scene Im not finding a way to edit it with a controller. What am I doing wrong?
Below is what I have so far and I must say I dont like the way I initialize the first 2 scenes from Main and of course trying to start the settings scene is rather haphazard. My hurdle now is trying to interact with the scenes through their controllers.
Main.java
package sample;
import javafx.application.Application;
import javafx.stage.Stage;
import sample.controllers.StageController;
<pre>
public class Main extends Application
{
#Override
public void start(Stage primaryStage) throws Exception
{
StageController newStage = new StageController();
newStage.start(primaryStage);
}
public static void main(String[] args) {
launch(args);
}
}
StageController.java
package sample.controllers;
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.util.List;
import static sample.controllers.HotkeyController.createHotkeys;
import static sample.controllers.WebViewController.createWebView;
/**
* Created by devin on 4/14/16.
*/
public class StageController extends Application
{
#Override
public void start(Stage primaryStage)throws Exception
{
Screen primaryScreen = Screen.getPrimary();
Screen secondaryScreen;
List<Screen> allScreens = Screen.getScreens();
if (allScreens.size() <= 1)
{
System.out.println("Only one screen");
secondaryScreen = primaryScreen;
}
else
{
if (allScreens.get(0).equals(primaryScreen))
{
secondaryScreen = allScreens.get(1);
}
else
{
secondaryScreen = allScreens.get(0);
}
}
configureStage("Primary", primaryStage, primaryScreen);
final Stage secondaryStage = new Stage();
configureStage("Secondary", secondaryStage, secondaryScreen);
}
private void configureStage(final String name, final Stage stage, final Screen screen)
{
Rectangle2D bounds = screen.getBounds();
System.out.println(name + ":" + bounds);
stage.setX(bounds.getMinX());
stage.setY(bounds.getMinY());
stage.setWidth(bounds.getWidth());
stage.setHeight(bounds.getHeight());
stage.initStyle(StageStyle.UNDECORATED);
showStage(name, stage, screen);
stage.show();
stage.setFullScreen(true);
}
private void showStage(final String name, final Stage stage, final Screen screen)
{
//Scene scene = new Scene(new Group());
StackPane root = new StackPane();
Scene scene = new Scene(root);
stage.setScene(scene);
createWebView(name, root);
scene.setRoot(root);
/*
* Use hotkeys to allow application actions
*/
createHotkeys(name, scene);
}
}
WebViewController
package sample.controllers;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import org.w3c.dom.Document;
/**
* Created by devin on 4/13/16.
*/
public class WebViewController
{
public static void createWebView(final String name, final StackPane root)
{
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
if (name == "Primary") {
webEngine.load("http://google.com");
}
else
{
webEngine.load("http://google.com");
}
webEngine.documentProperty().addListener(new ChangeListener<Document>()
{
#Override public void changed(ObservableValue<? extends Document> prop, Document oldDoc, Document newDoc)
{
String heightText = browser.getEngine().executeScript(
"window.getComputedStyle(document.body, null).getPropertyValue('height')"
).toString();
double height = Double.valueOf(heightText.replace("px", ""));
System.out.println("Height of browser on " + name + " " + height);
}
});
root.getChildren().addAll(browser);
/* This is a firebug call if we need to debug the webpage that is being loaded */
// webEngine.documentProperty().addListener(new ChangeListener<Document>() {
// #Override public void changed(ObservableValue<? extends Document> prop, Document oldDoc, Document newDoc) {
// enableFirebug(webEngine);
// }
// });
}
private static void enableFirebug(final WebEngine engine) {
engine.executeScript("if (!document.getElementById('FirebugLite')){E = document['createElement' + 'NS'] && document.documentElement.namespaceURI;E = E ? document['createElement' + 'NS'](E, 'script') : document['createElement']('script');E['setAttribute']('id', 'FirebugLite');E['setAttribute']('src', 'https://getfirebug.com/' + 'firebug-lite.js' + '#startOpened');E['setAttribute']('FirebugLite', '4');(document['getElementsByTagName']('head')[0] || document['getElementsByTagName']('body')[0]).appendChild(E);E = new Image;E['setAttribute']('src', 'https://getfirebug.com/' + '#startOpened');}");
}
}
HotkeyController.java
package sample.controllers;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
/**
* Created by devin on 4/13/16.
*/
public class HotkeyController
{
public static void createHotkeys(final String name, final Scene scene)
{
final KeyCombination exitCMD = new KeyCodeCombination(KeyCode.E, KeyCombination.CONTROL_DOWN);
scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>()
{
#Override
public void handle(KeyEvent event)
{
if (exitCMD.match(event))
{
System.out.println("CTRL + E was pressed on " + name + " display\n" +
"Exiting the application");
Platform.exit();
}
}
});
final KeyCombination settingsCMD = new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN);
scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>()
{
#Override
public void handle(KeyEvent event)
{
if (settingsCMD.match(event))
{
System.out.println("CTRL + S was pressed on " + name + " display\n" +
"Opening Settings Scene");
/*
* This is where we need to launch a scene for settings
*/
try
{
Parent root = FXMLLoader.load(getClass().getResource("/sample/view/settingsscreen.fxml"));
Stage settingsStage = new Stage();
settingsStage.setTitle("FTX Signage Settings");
settingsStage.setScene(new Scene(root, 500 , 400));
settingsStage.show();
// SettingsController settingsController = new SettingsController();
// GettersSetters getSet = new GettersSetters();
// settingsController.getText();
// String hostname = getSet.getHostname();
// settingsController.setText(hostname);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
});
}
}

JavaFX use parsed variables during initialize

I know how to parse variables to controllers in JavaFX with fxml. But i need to use them in the initialize method of my controller. Is there a ways to do this? The background is, that i have a interface, where you can define different settings. Now you can safe them and have to be able to reopen them. So now when i open a rule, i need to set the values in the new option view. I know, that it works on text fields (UI-Elements) to set Text during initialize but not for variables. I tried different approaches. Like binding with properties (works for visibility property of button (UI-Element) but not for variables to set. Do you know a way or maybe an other approach?
Here is my example:
Controller1:
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.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;
/**
*
* #author Sandro
*/
public class FXMLDocumentController implements Initializable {
#FXML
private Button btn_openWindow;
#FXML
private void handleButtonAction(ActionEvent event) {
try {
Stage stage = new Stage();
FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(getClass().getResource("fxml_second.fxml").openStream());
Fxml_secondController cont = (Fxml_secondController)loader.getController();
cont.setFlag(0x00000002);
cont.setIsChange(false);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
btn_openWindow.setOnAction(this::handleButtonAction);
}
Controller 2:
/**
* FXML Controller class
*
* #author Sandro
*/
public class Fxml_secondController implements Initializable {
#FXML private Button btn_printOut;
private boolean isChange = true;
private int flag = 0x00000001;
private void printOut(ActionEvent event){
System.out.println("isChange: "+isChange);
System.out.println("flag: "+flag);
}
public boolean isIsChange() {
return isChange;
}
public void setIsChange(boolean isChange) {
this.isChange = isChange;
}
public int getFlag() {
return flag;
}
public void setFlag(int flag) {
this.flag = flag;
}
#Override
public void initialize(URL url, ResourceBundle rb) {
btn_printOut.setOnAction(this::printOut);
System.out.println(flag);
}
In controller 2 you see the problem. The console-output in initialize shows 1 but it need to show 2. If i klick on printOut (Button) it prints out the right values which i have set in Controller 1.
Set the controller in the Java code, instead of in FXML.
Remove the fx:controller attribute from fxml_second.fxml, and change the code in FXMLDocumentController as follows:
#FXML
private void handleButtonAction(ActionEvent event) {
try {
Stage stage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml_second.fxml"));
Fxml_secondController cont = new Fxml_secondController();
cont.setFlag(0x00000002);
cont.setIsChange(false);
loader.setController(cont);
Parent root = loader.load();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
Another option would be to use a custom component approach for the second fxml.

Pointer exception in JavaFx when trying to recplace scene content

I just started Java and getting some GUI with Fx but I get an null pointer exception when trying to replace my scenecontent.
In the main the Login.fxml is loaded without any problem but when I click to the button for switching to another fxml I get the error.
The main:
package application;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
private Stage stage;
#Override
public void start(Stage primaryStage) {
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("Login.fxml"));
} catch (IOException e) {
e.printStackTrace();
return;
}
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void gotoMainView() {
try {
MainViewController profile = (MainViewController) replaceSceneContent("MainView.fxml");
profile.setApp(this);
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
void Userlogin()
{
gotoMainView();
}
private void gotoLogin() {
try {
LoginController login = (LoginController) replaceSceneContent("Login.fxml");
login.setApp(this);
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
private Initializable replaceSceneContent(String fxml) throws Exception {
FXMLLoader loader = new FXMLLoader();
InputStream in = Main.class.getResourceAsStream(fxml);
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(Main.class.getResource(fxml));
AnchorPane page;
try {
page = (AnchorPane) loader.load(in);
} finally {
in.close();
}
Scene scene = new Scene(page, 800, 600);
stage.setScene(scene);
stage.sizeToScene();
return (Initializable) loader.getController();
}
}
The Logincontroller class:
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
public class LoginController extends AnchorPane implements Initializable {
#FXML
static private Button btntext;
#FXML
static private TextField loginusr;
#FXML
static private PasswordField loginpwd;
private Main application;
public void setApp(Main application){
this.application = application;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
btntext.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
System.out.println(loginusr.getText());
System.out.println(loginpwd.getText());
application.Userlogin();
}
});
}
The error occurs at:
application.Userlogin();
Many thanks in advance
The initialize() method is called as soon as the FXML is loaded. Have a look here
Your initialize() is called before setApp(Main application). At this point of time, the application object has not been initialized and is null !
This means the initialize() method is called at
MainViewController profile = (MainViewController) replaceSceneContent("MainView.fxml");
whereas application object which is used inside the initialize() is instantiated after this line, when you are using
profile.setApp(this);
So when you are trying the code application.Userlogin(); inside initalize(), at the time of execution, application is null !

Categories