I was doing this tutorial in JavaFX and got a null pointer exception on the line marked by " <<--NullPointerException". I just couldnt understand why this is happening. Any help? The method to which "this" goes is also given. The rest of codes are pretty much correct Im sure. The error description is also given.
public class MainApp extends Application{
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Person> personData = FXCollections.observableArrayList();
public MainApp() {
personData.add(new Person("Stefan", "Meier"));
personData.add(new Person("Martin", "Mueller"));
}
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
try {
FXMLLoader loader = new FXMLLoader(ClassLoader.getSystemResource("sample.fxml"));
rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException iox){
iox.printStackTrace();
}
showPersonOverview();
}
public Stage getPrimaryStage() {
return primaryStage;
}
public void showPersonOverview() {
try {
FXMLLoader loader = new FXMLLoader(ClassLoader.getSystemResource("fxcontroller.fxml"));
AnchorPane overviewPage = (AnchorPane) loader.load();
rootLayout.setCenter(overviewPage);
// Give the controller access to the main app
Controller controller = loader.getController();
controller.setMainApp(this); // <<--NullPointerException
} catch (IOException e) {
e.printStackTrace();
}
}
public ObservableList<Person> getPersonData(){
return personData;
}
public static void main(String[] args) {
launch(args);
}
}
method setMainApp() in Class Controller. The other codes in this class is correct that I'm sure as most are just set and get or create buttons and labels.
#FXML
private TableView<Person> personTable;
private MainApp mainApp;
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
personTable.setItems(mainApp.getPersonData());
}
This is first portion of fxcontroller.fxml file which gives AnchorPane
<?xml version="1.0" encoding="UTF-8"?>
//import statements
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
.....
The error message:
Exception in Application start method
java.lang.reflect.InvocationTargetException
....
Caused by: **java.lang.NullPointerException**
....
Sorry to make the description too long. I wish I knew how to make it shorter.
Your controller cannot be loaded. That's why you get nullpointerexception.
may be controller path is wrong
or you did some mistake to specify controller in fxml file
Related
I need to pass a Stage to my Filechooser in the Controller Class.
For that I need to set a Controller in my MainDesignClass.
What is wrong here:
#Override
public void start( Stage primaryStage) throws Exception{
FXMLLoader loader= new FXMLLoader(getClass().getResources("myfxml.fxml");
Parent root =(Parent)loader.load();
primaryStage = new Stage();
Controller myController=loader.getController();
myController.setStage(primaryStage);
primaryStage.setTitle("myapp");
primaryStage.getIcons().add(image);
primaryStage.setScene(new Scene(root,900,600));
primaryStage.show();
}
setStage is marked red. But why? Why it cannot find the method? How can I use FileChooser then in my Controller.class ?
To use Controller you must set it in your FXML file in a parent object like this
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="157.0" prefWidth="430.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controllers.Controller">
Ok, I got this solved:
Main Class
public class Main extends Application {
private static Stage primaryStage; // Declare static Stage, so it can also be accessed in the controller and if you walk through Files!
private void setPrimaryStage(Stage stage) {
Main.primaryStage = stage;
}
static public Stage getPrimaryStage() {
return Main.primaryStage;
}
#Override
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage); // **Set the Stage**
//get new instance of FXMLLoader
FXMLLoader loader= new FXMLLoader(getClass().getResources("myfxml.fxml");
Parent root =(Parent)loader.load();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
}
instanceofmain.getPrimaryStage()
In Controller Class
public class Controller {
private Main mymainclass; //you need an instance of the main class to open the stage on this very instance, as it is static you will be able to get it then.
public void onMouseClickAction(ActionEvent e) {
Stage s = mymainclass.getPrimaryStage();
// do not apply any close actions, as you want to stay on the same stage
FileChooser chooser= new Filechooser();
File defaultfile = chooser.showOpenDialog(s); // for directories the command is showDialog(s);
}
}
There were no other threads related to my specific problem.
Hello i starting my adventure with javafx, i use SceneBuilder to make theme,
this is my XmlFile:http://pastebin.com/9fvhREKc
controller:
public class Controller {
#FXML
private ListView templates;
#FXML
private ImageView image;
#FXML
void initalize() {
ObservableList elements = FXCollections.observableArrayList();
elements.add("first");
elements.add("second");
elements.add("third");
image.setImage(new Image("file:test.jpg"));
templates.setItems(elements);
}
}
and my main class
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(this.getClass().getResource("Sample.fxml"));
Controller controller = new Controller();
loader.setController(controller);
Pane root = loader.load();
Scene scene = new Scene(root);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
and when i start application my theme work but list and image is empty;/
You need to set the controller before you load the FXML, since the controller's initialize method is invoked as part of the load() process:
FXMLLoader loader = new FXMLLoader();
loader.setLocation(this.getClass().getResource("Sample.fxml"));
Controller controller = new Controller();
loader.setController(controller);
Pane root = loader.load();
Scene scene = new Scene(root);
Also note you have a typo in your Controller class: the method name initialize is misspelled. Since the FXMLLoader uses reflection to find and execute this method, this will prevent the method from being executed:
public class Controller {
#FXML
private ListView templates;
#FXML
private ImageView image;
#FXML
// void initalize() {
void initialize() {
ObservableList elements = FXCollections.observableArrayList();
elements.add("first");
elements.add("second");
elements.add("third");
image.setImage(new Image("file:test.jpg"));
templates.setItems(elements);
}
}
I am just beginning to learn JAVAFX and I have run into a problem now. I have a login screen and after I clicked login, a dialog box appeared and the problem is I don't know how to eliminate the login screen after the dialog has showed up. Please help me. This is my code
Main.java (contains login screen)
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("../view/LoginScreen.fxml"));
primaryStage.setTitle("Weltes Mart O2 Tank Module");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
LoginController.java (showing a dialog box)
public class LoginController {
#FXML private Text loginStatusMessage;
#FXML private Button btnLogin;
#FXML public void handleLoginButton(ActionEvent event){
System.out.println("BUTTON PRESSED");
try {
Parent root = FXMLLoader.load(getClass().getResource("../view/LoginSuccessDialog.fxml"));
Stage primaryStage = new Stage();
primaryStage.setScene(new Scene(root));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
You can use any Node in a Scene to get a reference to that scene. You can use a Scene to get the Window that contains it. You can close that window.
Assuming the Node fields are actually injected by the loader, you can close the Stage using this code:
btnLogin.getScene().getWindow().hide();
My application has a Login Scene and a Main View Scene, what is happening is when I do my login and MainView is called SOMETIMES I get this exception:
java.lang.NullPointerException
at javafx.scene.Scene.focusInitial(Scene.java:1879)
at javafx.scene.Scene.access$3600(Scene.java:170)
at javafx.scene.Scene$ScenePulseListener.focusCleanup(Scene.java:2181)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2221)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:363)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:460)
at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:329)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Thread.java:722)
The curious is it doesn't happening always, just sometimes.
My class:
public class TargetAppDesktop extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
Scene scene = new Scene(new AnchorPane());
LoginManager loginManager = new LoginManager(scene);
loginManager.showLoginScreen();
primaryStage.setResizable(false);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent t) {
MainViewController.deleteTempFiles();
Platform.exit();
System.exit(0);
}
});
}
public static void main(String[] args) {
launch(args);
}
}
MY LOGIN MANAGER CLASS
public class LoginManager {
private Scene scene;
LoginManager(Scene scene) {
this.scene = scene;
}
public void logout() {
showLoginScreen();
}
void showLoginScreen() {
try {
FXMLLoader loader = new FXMLLoader(
getClass().getResource("Login.fxml"));
// scene.getStylesheets().add(this.getClass().getResource("Login.css").toExternalForm());
scene.setRoot((Parent) loader.load());
LoginController controller =
loader.<LoginController>getController();
controller.initManager(this);
} catch (IOException ex) {
Logger.getLogger(LoginManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
void showMainViewScreen(Login loginTargetApp, Login loginGateway, Gateway gateway, File file, ArrayList<Integer> anoList) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MainView.fxml"));
scene.setRoot((Parent) loader.load());
MainViewController controller = loader.<MainViewController>getController();
controller.initSessionID(this, scene, loginTargetApp, loginGateway, gateway, file, anoList);
} catch (Exception ex) {
Logger.getLogger(LoginManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
void autheticated(Login loginTargetApp, Login loginGateway, Gateway gateway, File file, ArrayList<Integer> anoList) {
showMainViewScreen(loginTargetApp, loginGateway, gateway, file, anoList);
}
}
This problem was ocurring because I was trying to change my scene in another Thread, but it must to be changed in a Javafx Main Thread, so a simple Platform.runLater solved my problem.
More detail you can find here. (JIRA link)
Is there any way of getting the Stage/Window object of an FXML loaded file from the associated class controller?
Particularly, I have a controller for a modal window and I need the Stage to close it.
I could not find an elegant solution to the problem. But I found these two alternatives:
Getting the window reference from a Node in the Scene
#FXML private Button closeButton ;
public void handleCloseButton() {
Scene scene = closeButton.getScene();
if (scene != null) {
Window window = scene.getWindow();
if (window != null) {
window.hide();
}
}
}
Passing the Window as an argument to the controller when the FXML is loaded.
String resource = "/modalWindow.fxml";
URL location = getClass().getResource(resource);
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
Parent root = (Parent) fxmlLoader.load();
controller = (FormController) fxmlLoader.getController();
dialogStage = new Stage();
controller.setStage(dialogStage);
...
And FormController must implement the setStage method.
#FXML
private Button closeBtn;
Stage currentStage = (Stage)closeBtn.getScene().getWindow();
currentStage.close();
Another way is define a static getter for the Stage and Access it
Main Class
public class Main extends Application {
private static Stage primaryStage; // **Declare static Stage**
private void setPrimaryStage(Stage stage) {
Main.primaryStage = stage;
}
static public Stage getPrimaryStage() {
return Main.primaryStage;
}
#Override
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage); // **Set the Stage**
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
}
Now you Can access this stage by calling
Main.getPrimaryStage()
In Controller Class
public class Controller {
public void onMouseClickAction(ActionEvent e) {
Stage s = Main.getPrimaryStage();
s.close();
}
}