javafx repeat complex Fxml inside pane - javafx

I have design a complex fxml node with scene builder,
I want to repeat it in fxml file, so create a seperate fxml with the complex design, and I use the FXMLLoader ,
If I load the FXML in the initialize() method I get a infinity loop , the initialize function runs again and again.
If I put the fxml loader inside a button event, it works as expected but every time I call the fxml loader , the initialize function runs again,
So as I see I miss all the data ?
Is there any way to add context dynamic without running the initialize method again ?
FXMLLoader Relay_Output_Loader = new FXMLLoader(getClass().getResource("Relay_Output_Controller.fxml")); //Get FXML Loader
BorderPane_Relay_Output = Relay_Output_Loader.load(); //Get default Pane
Stack_Pane_Main_Controller.getChildren().add(BorderPane_Relay_Output);

Related

Adding tabs into a TabPane depending on the clicked button [duplicate]

This question already has an answer here:
How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?
(1 answer)
Closed 2 years ago.
I have a file named Home.fxml which is a BorderPane. This component has buttons on the left and an empty TabPane called mainTabPane in the centre. I would like, when a user clicks on any button on the left, to add a tab to mainTabPane. I am able to add one tab when one button is clicked. But when I try to do the same for the second button, I get this error:
java.lang.IllegalStateException: Location not set
Here is the code for HomeController.java, where all is done:
public void initialize(URL loc, Resource Rse) {
createReportsTab();
loadCreateItemTab();
}
/*this is the one which works well*/
#FXML
void CreateReportTab() {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(ReportsController.class.getResource("gui/Reports.fxml"));
Parent parent = loader.load();
Tab reportsTab = new Tab("Reporting Engine");
reportsTab.setClosable(true);
reportsTab.setcontent(parent);
mainTabPane.getTabs().add(reportsTab),
}
/*this is the one which produces the error*/
#FXML
void loadCreateItemTab() {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(AddNewItemController.class.getResource("gui/addNewItem.fxml"));
Parent parent = loader.load();
Tab newItemTab= new Tab("New Item");
newItemTab.setClosable(true);
newItemTab.setcontent(parent);
mainTabPane.getTabs().add(newItemTab),
}
I am confused; why the Reporting Engine loads well but the second one is producing that error above?
Here is my project structure in IntelliJ IDEA:
All controller classes are in the controllers package and all FXML files are in the GUI package. The main class is in Companion package.
Error suggests that addNewItem.fxml is not read. Change:
AddNewItemController.class.getResources("gui/addNewItem.fxml");
to
ReportsController.class.getResources("gui/addNewItem.fxml");
, since this path worked for you already.

Accessing nodes for a newly injected FXML file in javafx

I have an FXML file whose controller is set through:
fxmlloader.load(url);
fxmlloader.setController(<homeControllerObject>)
Now after a button click i load another fxml inside the current fxml with:
FXMLLoader fxmlLoader = new FXMLLoader();
Parent root = fxmlLoader.load(HomeController.class
.getResourceAsStream("sample.fxml"));
pane1.getChildren().add(root);
How can i access a label defined inside 'sample.fxml' in HomeController. I tried using
#FXML
private Label label;
at the top in HomeController but since the injection happens later on, value of label is always null.
Any ideas about how can i access those new nodes?
You should define an fx:id for your label and use this id as a field name. For example, if fx:id is myLabel then you can use it in your controller like this:
#FXML
Label myLabel;

Open a javafx fxml file in separate window on a button click without duplication

I use the below code to open a javafx fxml file in a different window on a button click event and it works fine. But if I click the same button again while the window opened it will create a duplicate window. Is there a possibly solutions to overcome this problem? Thanks in advance.
Parent parent = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Stage stage = new Stage(StageStyle.DECORATED);
stage.setTitle("Title");
stage.setScene(new Scene(parent));
stage.show();
I just stumbled upon this old question and figured I might answer it for anyone new to JavaFX or coding in general (I'm bored..).
In the provided code (see below) a new Stage is created every time, meaning that if this is run inside of a method you actually create a new Stage variable every time that the code is run:
Stage stage = new Stage(StageStyle.DECORATED);
What you could do instead create your Stage variable outside the method so that you either 1. just overwrite it every time or 2. have some "is showing" or a nullcheck or similar to see if a new stage should be created or if the existing one just needs to be shown.
For example:
private Stage stage;
private void onOpenNewStageBtnClicked(){
if(stage == null){
Parent parent = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
stage = new Stage(StageStyle.DECORATED);
stage.setTitle("Title");
stage.setScene(new Scene(parent));
}
stage.show();
}
Also, what I usually do is I create a Stage factory to avoid a lot of duplicate code and so that I can break out the creation of the stages and the loading of fxmls to other classes than my controller.

DataFX - how to get Parent?

Trying to start using DataFX ,, i wanna load an FXML view into another Pane, so i have a stage that is showing, on user action will add another FXML view to a Pane on the showing stage,
i usually do that this way :
fxmlLoader = constructFXMLLoader(FXMLPath);
root = (Parent) this.fxmlLoader.load();
private FXMLLoader constructFXMLLoader(String FXMLPath) {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getURL(stageFXMLName));
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
return fxmlLoader;
}
there i have the root so i can add it where ever i want, the question is how to do that with DataFX
i did a quick research but found nothing !
just figured out the answer
FlowHandler flowHandler = new Flow(Controller.class).createHandler();
flowHandler.getCurrentView().getViewContext().getRootNode();

Access elements of loaded FXML in Parent Controller

I currently have the following situation:
I have created a FXML file backed up by a FXML Controller. The screen consists of a sidebar and a child holder. When I click on an element in the sidebar, I load an additional FXML file in the child holder, like this:
childHolder.getChildren().addAll(FXMLLoader.load(getClass().getResource("SidebarItem1.fxml")));
This works fine. But I want to access some elements of the loaded FXML in the Controller of the Parent Controller. I just initialized the elements of the child FXML after I loaded it.
I already looked at this question: JAVAFX - FXML - Access Loaded FXML Controls from Parent Controller, but when I do it like that, I still get an error:
FXMLLoader loader = new FXMLLoader(getClass().getResource("SidebarItem1.fxml"));
loader.setController(this);
childHolder.getChildren().addAll(loader.load());
someChildTextField.setText("Some text");
I have given someChildTextField a fx:id and I have placed it on top of the initialize like this:
#FXML public TextField someChildTextField;
Still, I get a NullpointerException, so I assume it can still not find the control.
Does anyone know how to access elements of a loaded FXML in the Parent Controller?
I can't see any reason your approach doesn't work; I mocked something similar up and it worked just fine. This is an unusual approach, though, as you are using the same object as a controller for two separate FXML files.
I would recommend using one controller for each FXML. So you could do something like
public class SidebarItem1Controller {
#FXML
private TextField someTextField ;
public void setText(String text) {
someTextField.setText(text);
}
}
and then from your parent controller just do
FXMLLoader loader = new FXMLLoader(getClass().getResource("SidebarItem1.fxml"));
childHolder.getChildren().add(loader.load());
SideBarItem1Controller childController = loader.getController();
childController.setText("Some Text");
Set the controller in your SideBarItem1.fxml file the usual way, with fx:controller = com.example.SidebarItem1Controller"

Resources