NullPointerException when trying to access JavaFX button - javafx

I'm getting a NullPointerException when trying to access a Button from within initialize() method.
I have marked the line below which causes the exception.
public class MyController implements Initializable {
#FXML
public Button connect;
public MyController() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Layouts/ClientLayout.fxml"));
loader.setController(this);
Parent root = loader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root, 460, 470));
stage.show();
}
#Override
public void initialize(URL location, ResourceBundle resources) {
connect.setOnAction(e -> { // this line causes the nullpointerexception
connect.setDisable(true);
});
}
}

You did not initialize your button. Check your FXML. It should contain the correct fx:id:
<Button fx:id="connect" graphicTextGap="2.0" layoutX="716.0" layoutY="274.0" mnemonicParsing="false">
You should also define what do to on action with the addition of an onAction method in your FXML:
<Button fx:id="connect" graphicTextGap="2.0" layoutX="716.0" layoutY="274.0" mnemonicParsing="false" onAction="#handleConnectButtonAction">
and in your controller instead of putting it in the initialize method:
#FXML
private void handleConnectButtonAction(ActionEvent event){
connect.setDisable(true);
}

Related

Using JavaFX to pass data to an already opened window

I'm new to JavaFX. This was easy to do without FXML, but the FXML controllers are stumping me.
What I'm trying to do: Set up a main window that has a button. When clicked, the button launches a second popup window in which the user submits a value. Upon closing the second window (done currently with a button click on the pop-up), I'd like the user's input to be passed back to the main controller-- the main window that is already open.
So far, I've got 2 .fxml files(one for a main window the other for a popup), and the corresponding controllers: MainWindowController:
public class MainController implements Initializable {
#FXML
public Label label;
#FXML
private Button button;
#FXML
private void popBtnClick(ActionEvent event) throws IOException {
//creates new pop-up window
Stage popupSave = new Stage();
popupSave.initModality(Modality.APPLICATION_MODAL);
popupSave.initOwner(ComWins.stage);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("PopUp.fxml"));
Parent root = loader.load();
PopUpController controller = loader.getController();
//calls a method in the PopUpController, and uses it to pass data to
//the Popup window.
controller.dataToPopUp(7);
Scene scene = new Scene(root);
popupSave.setScene(scene);
popupSave.showAndWait();
}
I also tried calling this method from the popup window with no success in
changing Main's label.
public void dataPass(String name){
label.setText(name);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
And PopUpController:
public class PopUpController implements Initializable {
#FXML
private Button ok_btn;
#FXML
public TextField input_tf;
#FXML
private String input;
#FXML
private void okBtnClick() throws IOException {
input = input_tf.getText();
/*my attempt to pass the variable-- using a loader to get the
controller and then referencing the public label. */
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("Main.fxml"));
Parent root = loader.load();
FXMLDocumentController controller = loader.getController();
//this line works, and retrieves the label's text.
String temp = controller.label.getText();
//but this line does not work. Why?
controller.label.setText(input);
//closes this pop-up
Stage stage = (Stage)input_tf.getScene().getWindow();
stage.close();
}
//this method is called in the maincontroller and used to pass data to
//the popup's textfield.
public void dataToPopUp(int x){
input_tf.setText(Integer.toString(x));
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Using the above, Main passes ('7') into the PopUp's textfield. But if the user enters something else into the textfield, I cannot seem to get that data back to Main. This is like having a Settings Pop-up window, and then passing the user's selections from the Settings popup back to the main window. I just cannot figure out how to pass things back to the main window.
I am not using SpringBoot, but thanks for the suggestion.
Thank you in advance!
If you are using Spring Boot, MPV Java on YouTube has great examples of connecting your controllers together allowing you to pass information cleanly and easily between them.In my application I've been able to implement these examples. Each controller is registered as a bean using #Component which means you can #Autowire the controller into another controller. In your main controller I would recommend setting up some basic getters/setters to allow outside interaction with your fields so other controllers can "talk" to the main controller.
A really basic example would be:
#Component
public class MyMainController {
#FXML private TextField exampleTextField;
...
...
/* Get the text of a field from this controller: can be accessed from another controller */
public String getExampleTextField() {
exampleTextField.getText();
}
/* Set the text of a field on this controller: can be accessed from another controller */
public void setExampleTextField(String text) {
exampleTextField.setText(text);
}
}
#Component
public class AnotherController {
#Autowired private MyMainController myMainController;
...
...
public void someMethod(String newText) {
// Do some work here and set some text back to the main controller
myMainController.setExampleTextField(newText);
}
}
MPV Java does a much better job of explaining this concept.
https://www.youtube.com/watch?v=hjeSOxi3uPg
I reviewed the suggestions and was unable to get anything to work for me-- many of the concepts were over my head, as I'm new to Java. After several attempts, I was able to get a fairly simple solution to the problem. It is likely far from best practices, but it works:
In the main window's controller, use the popup's controller to call the Pop Up's string variable and set it as the label's text (label.setText(controller.test)). The string variable has to be public, and is set once the pop-up is closed by the button click. See the code below:
Main.fxml:
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="switchingpass.MainController">
<children>
<Button fx:id="button" layoutX="126" layoutY="90" onAction="#popBtnClick" text="Click Me!" />
<Label fx:id="label2" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
<Label fx:id="label" layoutX="143.0" layoutY="38.0" text="Label" />
</children>
</AnchorPane>
MainController:
public class MainController implements Initializable {
#FXML
public Label label;
#FXML
private Button button;
#FXML
private void popBtnClick(ActionEvent event) throws IOException {
//creates new pop-up window
Stage popupSave = new Stage();
popupSave.initModality(Modality.APPLICATION_MODAL);
popupSave.initOwner(SwitchingPass.stage);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("PopUp.fxml"));
Parent root = loader.load();
PopUpController controller = loader.getController();
Scene scene = new Scene(root);
popupSave.setScene(scene);
popupSave.showAndWait();
//after the popup closes, this will run, setting the label's text to the popup's test variable, which is public.
label.setText(controller.test);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
PopUp.fxml:
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="switchingpass.PopUpController">
<children>
<TextField fx:id="input_tf" layoutX="207.0" layoutY="65.0" />
<Button fx:id="close_btn" layoutX="268.0" layoutY="185.0" mnemonicParsing="false" onAction="#closeBtnClick" text="Close" />
</children>
</AnchorPane>
PopUpController:
public class PopUpController implements Initializable {
#FXML
public Button close_btn;
#FXML
public TextField input_tf;
#FXML
public String test;
#FXML
private void closeBtnClick() throws IOException {
//stores textfield input as a string
test = input_tf.getText();
Stage stage = (Stage)input_tf.getScene().getWindow();
stage.close();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Please note that the code's main class that extends Application must declare the stage variable as a public static variable:
public class SwitchingPass extends Application {
//this is necessary to initialize the owner of the popup
public static Stage stage;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Again, probably not the best way to accomplish this, but it works, and perhaps it is helpful to someone else.
I did that this way.
First create an interface
public interface DataSender {
void send(String data);
}
and then implement that interface to your Main Window Controller
public class FXMLDocumentController implements Initializable,DataSender {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
try {
Stage popupSave = new Stage();
popupSave.initModality(Modality.NONE);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("PopUp.fxml"));
Parent root = loader.load();
PopUpController controller = loader.getController();
controller.setX(7);
//this is the line use to get data from popup
controller.setSendDataSender(this);
Scene scene = new Scene(root);
popupSave.setScene(scene);
popupSave.show();
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
//this method can call from popus controller
#Override
public void send(String data) {
label.setText(data);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
and then override implemented interface method and inside the method you can change Main window UI data I changed label text.
and then create variable in pupup controller with type DataSender(created interface befor) and create method to set that interface
public class PopUpController implements Initializable {
private int x;
//this is the variable
private DataSender dataSender;
#FXML
private Button btnOk;
#FXML
private TextField txtText;
#Override
public void initialize(URL url, ResourceBundle rb) {
btnOk.setOnAction(e->{
//When Click this button will call Main Window send method
dataSender.send(txtText.getText());
});
}
public void setX(int x){
this.x=x;
}
//this is the method to set variable value from Main Window
public void setSendDataSender(DataSender ds){
this.dataSender=ds;
}
}
and then when popup window button clicked then call send method with data and then will change main window label text.
This solution is work for me.hope this useful for you also .

How to add a javafx shortcut key combinations for buttons

My UI has a adding button and I want to assign a keyboard shortcut combination for that. I have failed to use the setAcceleartor for this purpose.
What is the easiest way to set up keyboard shortcuts in javafx applications?
button declaration in the UI:
<Button fx:id="addButton" alignment="CENTER" minWidth="-Infinity" mnemonicParsing="false" onAction="#addAction" prefHeight="31.0" prefWidth="130.0" text="Add" HBox.hgrow="ALWAYS" />
Controller button binding:
#FXML
private Button addButton;
The method that wants to setOnAction for the shortcut for the button:
public void addAction(ActionEvent event) throws SQLException, ClassNotFoundException {
if (validateInput()) {
String productName = productField.getText();
double unitPrice = Double.parseDouble(priceField.getText());
int quantity = Integer.parseInt(quantityField.getText());
double total = unitPrice * quantity;
ITEMLIST.add(new Item(productName, unitPrice, quantity, total));
calculation();
resetAdd();
productTableView.getSelectionModel().clearSelection();
ObservableList<Product> productsData = ProductDAO.searchProducts();
populateProducts(productsData);
searchField.setText("");
}
}
initialize() method:
#FXML
private void initialize() throws SQLException, ClassNotFoundException, IOException {
setSaveAccelerator(addButton);
}
The code I tried with setAccelerator:
private void setSaveAccelerator(final Button button) {
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
In your setSaveAccelerator method, instead of directly calling addAction(ActionEvent event), just instruct the button to fire its event to its listeners such as: button.fire(). For example:
private void setSaveAccelerator(Button button) {
if(button==null) {
System.out.println("Button is null! "); // check that the button was injected properly through your fxml
}
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
EDIT
To also avoid the IllegalArgumentException you must attach the accelerator after the button is attached to a scene. I managed to achieve this by creating a public method in the controller to attach the accelerator after the scene has been set. Then, in the class where the scene is loaded the controller's method can be called which sets up this functionality. See the example below:
In the controller class (in my case MainController):
public void setup() {
setSaveAccelerator(button);
}
In your main class when loading the fxml file:
FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
AnchorPane page = (AnchorPane) loader.load();
MainController controller = loader.getController();
Scene scene = new Scene(page);
controller.setup(); // calls the setup method attaching the accelerators
FULL EXAMPLE
Main class:
public class Main extends Application{
public static Stage primaryStage;
#Override
public void start(Stage primaryStage) throws Exception {
Main.primaryStage=primaryStage;
FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
AnchorPane page = (AnchorPane) loader.load();
MainController controller = loader.getController();
Scene scene = new Scene(page);
primaryStage.setTitle("Shortcut example");
primaryStage.setScene(scene);
controller.setup();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Maincontroller:
public class MainController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button button;
#FXML
private AnchorPane rootPane;
#FXML
private TextArea textarea;
#FXML
void action(ActionEvent event) {
textarea.setText("Action fired!!");
}
#FXML
void initialize() {
assert button != null : "fx:id=\"button\" was not injected: check your FXML file 'MainFXML.fxml'.";
assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'MainFXML.fxml'.";
assert textarea != null : "fx:id=\"textarea\" was not injected: check your FXML file 'MainFXML.fxml'.";
}
public void setup() {
setSaveAccelerator(button);
}
private void setSaveAccelerator(Button button) {
if(button==null) {
System.out.println("Button null!!");
}
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
}
MainFXML.fxml
<AnchorPane fx:id="rootPane" prefHeight="408.0" prefWidth="330.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<Button fx:id="button" layoutX="139.0" layoutY="350.0" mnemonicParsing="false" onAction="#action" text="Button" />
<TextArea fx:id="textarea" layoutX="73.0" layoutY="38.0" prefHeight="200.0" prefWidth="200.0" />
</children>
</AnchorPane>

accessing a Pane from another class in javafx

I am unable to access from another class, I have created two pane with different controllers in one FXML File, second pane has to move around the first pane, on Click Action, and I have loaded an FXML file in second pane, also successfully moved the pane one time, but the second time I want to move it from second controller, but it is giving me an NullPointerException.
this is my main controller where I have moved the pane:
public class MainController implements Initializable {
#FXML
private Pane searchPane;
#FXML
private Pane secondPane;
private TranslateTransition nextTransition;
public Pane getSecondPane() {
return secondPane; // Accessing Pane with this getter method
}
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
private void nextBtnAction(ActionEvent event) {
try {
Parent pessFxml = FXMLLoader.load(getClass().getResource("firstPane.fxml"));
secondPane.getChildren().add(pessFxml);
nextTransition = new TranslateTransition(Duration.millis(300), secondPane);
nextTransition.setToX(searchPane.getLayoutX()-secondPane.getLayoutX());
nextTransition.play();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Form does not found" ,ex.toString(),0);
}
}
}
this is SecondController where I am accessing the pane to move it back smoothly, but its throwing NullPointerException:
please tell me how to solve this
public class SecondController implements Initializable {
MainController mainControll;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
private void backBtnPessAction(ActionEvent event) {
//here i am putting the second pane to move back
TranslateTransition back = new TranslateTransition(Duration.millis(300), mainControll.getSecondPane());
back.setToX(mainControll.getSecondPane().getLayoutX()-750);
back.play();
}
}
MainController is never initialized in SecondController. You should pass it when creating second controller in nextBtnAction.
MainController code:
private void nextBtnAction(ActionEvent event) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("firstPane.fxml"));
Parent pessFxml = loader.load();
SecondController controller = (SecondController)loader.getController();
controller.setMainController(this);
secondPane.getChildren().add(pessFxml);
nextTransition = new TranslateTransition(Duration.millis(300), secondPane);
nextTransition.setToX(searchPane.getLayoutX()-secondPane.getLayoutX());
nextTransition.play();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Form does not found" ,ex.toString(),0);
}
}
SecondController:
public void setMainController(MainController controller) {
this.mainControll = controller;
}

Changing the text of a label from a different class in JavaFX

This question was already asked here but was not able to find any answers. I have reproduced a similar situation where I would like to change the text of a label from another class using the controller
FXMLDocumentController.java
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Connector.Connecting();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setLabelText(String text)
{
System.out.println("FXMLDocumentController.setLabelText(): Called");
label.setText(text);
}
}
FXMLDocument.fxml
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="demo5.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>
Demo5.java
public class Demo5 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.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Connector.java
public class Connector {
public static void Connecting() {
try {
System.out.println("Connector.Connecting(): Called");
FXMLLoader loader = new FXMLLoader(FXMLDocumentController.class.getResource("FXMLDocument.fxml"));
loader.load();
FXMLDocumentController controller = (FXMLDocumentController) loader.getController();
controller.setLabelText("Bye World");
} catch (IOException ex) {
Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Output at Console
Connector.Connecting(): Called
FXMLDocumentController.setLabelText(): Called
But could see no changes in the label. Am I missing something major here ?
You can change your Connector class to receive the Controller instance:
public class Connector {
public static void Connecting(FXMLDocumentController controller) {
try {
System.out.println("Connector.Connecting(): Called");
controller.setLabelText("Bye World");
} catch (IOException ex) {
Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Connector.Connecting(this);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setLabelText(String text)
{
System.out.println("FXMLDocumentController.setLabelText(): Called");
label.setText(text);
}
}
Note:
If your Connector is going to take longer to execute whatever it needs to, you might want to use a Task, so you don't freeze your UI. To update the Label, you have to bind the text property and then update the Text value using the updateMessage() method.
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Task<Boolean> connectorTask = new ConnectorTask();
label.textProperty().bind(connectorTask.messageProperty());
connectorTask.setOnSucceeded(e -> {
// this is going to be called if the task ends up without error
label.textProperty().unbind();
});
new Thread(connectorTask).start();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
//public void setLabelText(String text)
//{
// System.out.println("FXMLDocumentController.setLabelText(): Called");
// label.setText(text);
//}
public class ConnectorTask extends Task<Boolean> {
#Override
protected Boolean call() throws Exception {
// ... do whatever you need here
// then you call this method to update the TextProperty from the Label that was bound.
updateMessage("Bye World");
return Boolean.TRUE;
}
}
}
Your Demo5 class and Connector class are both creating unique instances of the FXMLDocumentController via the call to FXMLLoader.load(). The instance in the Demo5 class is being placed in the scene graph and becomes visible. The instance in the connector is not being made visible. When you call setLabelText() it is changing the text for an unseen label. What you may want to do is get the FXMLDocumentController instance in Demo5 and provide it to the Connector class through the constructor or a setter method. You may need to change some things around depending on what the Connector class is used for. Alternatively, you could use the connector class to load the FXML root and controller and provide methods for accessing them, then use those methods in Demo5 to make the scene visible.
I made it in a simple way by defining the Label as static in the FXMLDocumentController.java:
#FXML GridPane myGridPane;
public static Label totLabel = new Label("Total");
and add it to myGridPane in the initialize method of FXMLDocumentController class:
#Override
public void initialize(URL url, ResourceBundle rb) {
myGridPane.add(totLabel, 0, 3);
}
and at any other class you can call the setText() of this label like this:
String message = "this message will appear in the total label";//your string
FXMLDocumentController.totLabel.setText(message);

JavaFX load FXML inside parent controller

I have a borderpane where I'm loading an fxml (alias FirstPanel) with relative controller inside of it and positioned in the center. The fxml contains a TableView and a button which should load another fxml (alias SecondPanel) and relative controller instead the first panel. Basically, the SecondPanel needs to show some details about the data selected in the table.
Is it possible to do it? How can I get the parent of my FirstPanel and use it for the SecondPanel instead of the first?
UPDATE
I've tried many solutions but without reach my goal. The application load the UsersMainPageController which contains only an AnchorPane like parent control, so this is the relative code:
[UsersMainPageController]
public class UsersMainPageController implements Initializable {
private PostOffice application;
#FXML
private AnchorPane ParentControl;
public void setApp(PostOffice application){
this.application = application;
}
public void loadPage(String pageName) {
try {
URL url = getClass().getResource(pageName);
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(url);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
AnchorPane page = (AnchorPane) fxmlLoader.load(url.openStream());
ParentControl.getChildren().clear();///name of pane where you want to put the fxml.
ParentControl.getChildren().add(page);
}
catch (IOException e) {
e.printStackTrace();
}
}
public void loadManageUsers () {
loadPage("UsersManage.fxml");
}
public void loadListUsers () {
loadPage("UsersList.fxml");
}
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
loadListUsers();
}
}
loadListUsers calls UsersList.fxml with the relative controller UsersListController that contains a TableView with some records and some buttons. When I click a specific button, it should call loadManageUsers with relative controller UsersManageController which contains some fields for editing data and inserting new users. When users are edited or inserted, it should be able to return to the previous page with the TableView and clear the current page (in this case UsersManageController).
[UsersListController]
public class UsersListController implements Initializable {
private UsersMainPageController mainController;
#FXML
private void handleButtonEditAction(ActionEvent event) throws IOException {
mainController.loadManageUsers();
}
}
[UsersManageController]
public class UsersManageController implements Initializable {
private UsersMainPageController mainController;
#FXML
private void handleButtonBackAction(ActionEvent event) throws IOException {
mainController.loadListUsers();
}
}
When I click from the UsersListController the ButtonEdit to load the UsersManageController, I get this error:
Caused by: java.lang.NullPointerException
at postoffice.multiuser.UsersListController.handleButtonAggiornaAction(UsersListController.java:210)
... 50 more
you can add your child fxml into parent controller..
1.first just take a anchor pane and set its bounds where you want to put your FXML code.
now try this...
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
openNewWindow("Example.fxml");
}
});
you can pass fxml name into function...
public void openNewWindow(String FXMLFile)
{
//ChildNode child;
try {
URL url = getClass().getResource(FXMLFile);
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(url);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
AnchorPane page = (AnchorPane) fxmlLoader.load(url.openStream());
anchor.getChildren().clear();///name of pane where you want to put the fxml.
anchor.getChildren().add(page);
}
catch (IOException e) {
e.printStackTrace();
}
}

Resources