i made a mainEntredController which contains a TabPane with two tabs (HomeController) and (PatientController), The MainEntred Controle the Parameter Passage Between this two tabs but i have liitls issu that the tabs doesnet reconize the Parent (MainEntredController) or each other. it retuns an error inn this line
*** labelpatient.setText(mainec.LoadtxtFromlabelhometabhome()); ******
the idea is to get a text from the first tab to show it in a label in the second tab
hear's my code
the first is the MainEntred Class the Container
public class MainEntredController {
#FXML MenuItem closemi;
#FXML HomeController homecontroller;
#FXML PatientController patientcontroller;
public void initialize(URL location, ResourceBundle resources) {
System.out.println("Application Started");
homecontroller.intit(this);
patientcontroller.init(this);
}
public void ClickMenuItemClose(){
System.exit(0);
}
public String LoadtxtFromlabelhometabhome() {
// System.out.println(homecontroller.labelhome.getText());
return homecontroller.labelhome.getText();
}
public void setTabpatientlabel(String text) {
//patientcontroller.labelpatient.setText(text);
}
}
the Second is the First Tab HomeController
public class HomeController {
public MainEntredController mainec;
#FXML public Label labelhome;
#FXML private TextField tfhome;
#FXML private Button savehome;
#FXML private Button sendhome;
//public HomeController(){}
public void btnSaveHomeClicked(ActionEvent event){
System.out.println("le boutton save home est cliqué");
labelhome.setText(tfhome.getText());
}
public void btnSendHomeClicked(ActionEvent event){
System.out.println("le boutton send home est cliqué");
// send data to tab patient
mainec.setTabpatientlabel(labelhome.getText());
}
public void intit(MainEntredController mainEntredController) {
mainec = mainEntredController;
}
}
the Third one is the Second tab PatientController
public class PatientController {
public MainEntredController mainec;
#FXML public Label labelpatient;
#FXML private TextField tfpatient;
#FXML private Button savepatient;
#FXML private Button loadpatient;
public void btnSavePatientClicked(ActionEvent event){
System.out.println("le boutton save Patient est cliqué");
labelpatient.setText(tfpatient.getText());
}
public void btnLoadPatientClicked(ActionEvent event){
System.out.println("le boutton Load patient est cliqué");
labelpatient.setText(mainec.LoadtxtFromlabelhometabhome());
}
public void init(MainEntredController mainEntredController) {
mainec = mainEntredController;
}
}
And the FXML File of the MainEntred
<fx:include id="homecontroller" source="home.fxml" />
<fx:include id="patientcontroller" source="patient.fxml" />
i guess those two are madding the problem any advise how to solve it Please
i dont know why i am having java.lang.NullPointerException at the line declarred erlier he cant get the source (unknown source)
If i understand correctly then you want to communicate between controller. well, this can be done pretty easy.
in you main type something likes this:
FXMLLoader loader = new FXMLLoader(Main.class.getResource("your.fxml"));
Parent node = loader.load(); // this loads view
YourController instance = loader.getController();
some_class.initialize(instance);
Finelly i found what is wrong. the thing is that in the declaration in the MainController of the two Tabs we put the fx:id declared on the fxml file
and adding the word "Controller"
like this
#FXML private HomeController homeController;
#FXML private PatientController patientController;
the fx:id="home"
the second includes fx:id="patient"
Related
I have an app with 3 fxml files.
The 1st is main window of app and most of work im doing here, but the 2 others fxml files allows me to change some settings and add more records to app.
I made it that 2 small fxml files extends the main file.
Basically:
public class FXMLDocumentController implements Initializable {
#FXML
private TextField txt;
#FXML
private Stage stage;
Symulacja symulacja = new Symulacja();
Promocja promocja = new Promocja();
#Override
public void initialize(URL url, ResourceBundle rb) {
txt.textProperty().bindBidirectional(promocja.getProgKwotyZetonow(), new NumberStringConverter());
labelProgKwotyZetonow.textProperty().bind(promocja.getProgKwotyZetonow().asString());
}
#FXML
public void zmienUstawienia() {
symulacja.zmienOkno("FXMLUstawienia.fxml", "Ustawienia");
}
#FXML
public void dodajKlientow() {
symulacja.zmienOkno("FXMLDodajKlienta.fxml", "Dodawanie");
}
}
It's main fxml Controller
public class FXMLUstawieniaController extends FXMLDocumentController{
#FXML
private TextField textProgKwota;
#FXML
private Button btnZatwierdzUstawienia;
#FXML
private TextField textProgIlosc;
#FXML
public void zatwierdzUstawienia() {
promocja.setProgIlosciZetonow(Integer.parseInt(textProgIlosc.getText()));
}
#Override
public void initialize(URL url, ResourceBundle rb) {
textProgKwota.textProperty().bindBidirectional(promocja.getProgKwotyZetonow(), new NumberStringConverter());
}
}
As you see I'm using properties to dynamically change what is showing in labelProgKwotyZetonow and textProgKwota.
When im not using the 2nd window txt and labelProgKwotyZetonow works fine, but when I'm initializing 2nd window I always get 0 in TextField and even if I change it this is not changing labelProgKwotyZetonow.
It's strange to me because when I'm souting (System.out.println) the value of promocja.getProgKwotyZetonow() in some places I get:
In function initialize in the 2nd controller - 0.
In function zmienUstawienia in 1st controller - the value from txt/labelProgKwotyZetonow.
In function zatwierdzUstawienia in 2nd controller - the value from textProgKwota.
Every time I ran JavaFX app I encounter the error below.
15:11:52.778 [JavaFX Application Thread] ERROR org.fhl.Manifesto - javafx.fxml.LoadException:
/C:/ManGenFX/target/classes/dataController.fxml
/C:/ManGenFX/target/classes/ManifestoMain.fxml:7
But it only happens if I add the initialize method on Main Controller.
public class MainController{
#FXML
GenerateController genCont;
#FXML
private Pane generatePane;
#FXML
AnchorPane mainFx;
private Node source;
//Other Button, TextFields and Labels declaration
#FXML
private void browseFile(ActionEvent x) {
//Browse file definition
}
#FXML
private void savePath(ActionEvent x) {
//Save file definition
}
//Problem with this method
#FXML
public void initialize() {
System.out.println("Initialize generate controller panel");
logger.info("Initialize generate controller panel");
genCont.init(this);
}
}
If I remove the initialize method on MainController class it will not throw any error but nothing happens either if I click on the generate button which is defined in GenerateController class below.
public class GenerateController {
#FXML
Button btnGenerate;
#FXML
Pane paneGen;
#FXML
public void generateMan(ActionEvent event) {
//generateMan body when Generate button is clicked
}
public void init(MainController mc) {
System.out.println("Init mainControl");
mainControl = mc;
}
public void validate() {
//Definition of method body here
}
}
This is the main Class
public class Man extends Application {
private Stage mainStage;
#Override
public void start(Stage primaryStage) {
this.mainStage = primaryStage;
this.mainStage.setTitle("Manifest");
try{
Parent root = FXMLLoader.load(getClass().getResource("/ManifestoMain.fxml"));
Scene sMain = new Scene(root);
mainStage.setScene(sMain);
mainStage.show();
}catch(IOException ioE) {
logger.error(ioE);
}
}
public static void main(String[] args) {
launch(args);
}
}
Also, I placed my dataController.fxml, ManifestoMain.fxml, and generateView.fxml under resources folder but it don't have any problem accessing the files. Appreciate help on this.
I have this function in the controller class of the relevant fxml. I need this function to be fired on focus out from a textfield, but scene builder doesn't have an event similar to onfocusout. How to achieve this using the control class?
#FXML
private void ValidateBikeNo(){
Tooltip error = new Tooltip("This bike no exists");
BikeNoIn.setTooltip(error);
}
You can attach a focusListener to the TextField and then execute the code inside it. The listener can be attached inside the initialize() method of the controller.
public class MyController implements Initializable {
...
#FXML
private Textfield textField;
public void initialize() {
...
textField.focusedProperty.addListener((ov, oldV, newV) -> {
if (!newV) { // focus lost
// Your code
}
});
.....
}
}
You have to use method textField.focusedProperty() instead of textField.focusProperty
public class MyController implements Initializable {
...
#FXML
private Textfield textField;
public void initialize() {
textField.focusedProperty().addListener((ov, oldV, newV) -> {
if (!newV) { // focus lost
// Your code
}
});
}
}
I'm trying to change a text in a label, a text which was entered in a text field in a different scene.
I made 2 FXML files, the first one contains a textfield and "ok" button, the second one contains a label(with the text "Label").
My goal is to enter a text in the textfield, and when I press "ok"-> open the new scene and the label will change it's text to the text I entered in the text field.
I easily changed the label text when the label, the textfield and the ok button were all in the same scene, but when I do it while opening a new scene I fail...
After some research, I made a controller for each FXML file, and a "MainController" that will communicate between them.
This is my main class:
public class MainBanana extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("view/Welcome.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("MokaApp");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setResizable(false);
}
public static void main(String[] args) {
launch(args);
}
}
my first scene controller:
public class WelcomeController {
#FXML
public TextField nameField;
#FXML
private Button okButton;
private MainController main;
#FXML
public void okClicked(ActionEvent event) throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("Person.fxml"));
okButton.getScene().setRoot(root);
System.out.println(nameField.getText());
main.setLblFromTf(nameField.getText());
}
public void init(MainController mainController) {
main=mainController;
}
}
second scene controller:
public class PersonController {
#FXML
public Label nameLabel;
private MainController main;
public void init(MainController mainController) {
main=mainController;
}
}
When I launch the program, The Welcome scene is opened, I enter a text to the textfield, but whenever I press the "ok" button, the scene changes to the second scene, but the label text stays the same(label) and I get a nullpointerexception error on this line(located in WelcomeController): main.setLblFromTf(nameField.getText());
Sorry for the long post..
You don't need the references to MainController all over the place.
The easiest way is:
public class PersonController {
#FXML
private Label nameLabel ;
public void setName(String name) {
nameLabel.setText(name);
}
}
Then you can do
public class WelcomeController {
#FXML
private TextField textField ;
#FXML
private Button okButton ;
#FXML
public void okClicked() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Person.fxml"));
Parent root = loader.load();
PersonController personController = loader.getController();
personController.setName(textField.getText());
okButton.getScene().setRoot(root);
}
}
I have a BorderPane, onto which I placed a MenuBar. At the center of the BorderPane I display differnt AnchorPanes depending on the MenuItem selected. So far so good.
Now, how do I make sure that the Menus change behavior in response to the item selected in the child AnchorPane? So for example if the user selects "Edit", there will be a different action depending on whether the item currently higlighted is a user account, a file etc.
So far I made something along these lines:
The BorderPane controller:
public class MenuTest implements Initializable{
#FXML
private BorderPane borderPaneMain;
#FXML
private AnchorPane anchorPaneMain;
#FXML
private Menu menuEdit;
#FXML
private MenuItem itemEdit;
static String menuMode;
static String entityName;
public MenuTest(){
menuMode ="";
entityName = "";
}
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
AnchorPane anchor;
try {
anchor = (AnchorPane) new FXMLLoader().load(getClass().getResource("views/MainView.fxml"));
borderPaneMain.setCenter(anchor);
} catch (IOException e) {
e.printStackTrace();
}
}
protected static void setMenuMode(String menuMd, String entityNm){
entityName = entityNm;
menuMode = menuMd;
}
#FXML
private void onEditClick(){
if(entityName.equals(AnchorTest.FILE)){
//Launches correct edit view
new FXMLLoader().load(getClass().getResource("views/EditFile.fxml"));
//Passes the name of the entity so that the controller can retrieve its data
FileEditController.setFile(entityName);
}else if(entityName.equals(AnchorTest.PERSON)){
new FXMLLoader().load(getClass().getResource("views/EditPerson.fxml"));
PersonEditController.setFile(entityName);
}
}
}
The child AnchorPane controller:
public class AnchorTest implements Initializable{
public static final String PERSON = "PERSON";
public static final String FILE = "FILE";
ObservableList<String> peopleList;
ObservableList<String> fileList;
#FXML
private ListView<String> listPeople;
#FXML
private ListView<String> listFiles;
#Override
public void initialize(URL location, ResourceBundle resources) {
peopleList = FXCollections.observableArrayList("Frank","Matin","Anne");
fileList = FXCollections.observableArrayList("hello.txt","holiday.jpg","cv.doc");
listPeople.setItems(peopleList);
listFiles.setItems(fileList);
}
#FXML
private void personSelected(){
MenuTest.setMenuMode(this.PERSON, listPeople.getSelectionModel().getSelectedItem());
}
#FXML
private void fileSelected(){
MenuTest.setMenuMode(this.FILE, listFiles.getSelectionModel().getSelectedItem());
}
}
However I'm not sure that it's the best solution, especially considering the if/elseif statement will need to be altered whenever I add a new element type and its corresponding edit options. So is there any way that I can do this better?
I think if your application has only a few (2-4) different types of "things" that are represented by a AnchorPane, then your approach is totally fine. An alternative to your approach is the state pattern. In that case, your currently selected "item type" would be your state.