Reputation: 15
I'm stuck in my code. I'm writting a library system, which contains many of controllers. This is my main controller fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<Pane prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.library.controllers.MainController">
<children>
<VBox>
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="Plik">
<items>
<MenuItem fx:id="Users" mnemonicParsing="false" onAction="#onUsersMenuAction" text="Użytkownicy" />
<MenuItem fx:id="Backup" mnemonicParsing="false" onAction="#onBackupMenuAction" text="Wykonaj kopię zapasową" />
<MenuItem fx:id="CloseProgram" mnemonicParsing="false" onAction="#onCloseProgramMenuAction" text="Zakończ" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Raporty">
<items>
<MenuItem fx:id="ActiveRentedBooks" mnemonicParsing="false" onAction="#onActiveRentedBooksMenuAction" text="Aktywne wypożyczenia" />
<MenuItem fx:id="ActiveBorrowers" mnemonicParsing="false" onAction="#onActiveBorrowersMenuAction" text="Aktualni dłużnicy" />
<MenuItem fx:id="ReportOfRentedBooksPerDay" mnemonicParsing="false" onAction="#onReportOfRentedBooksPerDayMenuAction" text="Raport wypożyczeń/dzień" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Słowniki">
<items>
<MenuItem fx:id="Categories" mnemonicParsing="false" onAction="#onCategoriesMenuAction" text="Kategorie" />
<MenuItem fx:id="UKDDictionary" mnemonicParsing="false" onAction="#onUKDDictionaryMenuAction" text="Słownik UKD" />
<MenuItem fx:id="ReasonsForDefects" mnemonicParsing="false" onAction="#onReasonForDefectsMenuAction" text="Powody ubytków" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Wydruki">
<items>
<MenuItem fx:id="PrintBookLabel" mnemonicParsing="false" onAction="#onPrintBookLabelActionButton" text="Drukuj etykietę książki" />
<MenuItem fx:id="PrintCardOfLoans" mnemonicParsing="false" onAction="#onPrintCardOfLoansMenuAction" text="Drukuj kartę wypożyczająćego" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Ustawienia">
<items>
<MenuItem fx:id="GeneralOptions" mnemonicParsing="false" onAction="#onGeneralOptionsMenuAction" text="Ogólne" />
</items>
</Menu>
</menus>
</MenuBar>
<TabPane prefHeight="547.0" prefWidth="800.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab fx:id="KBooks" text="Książki">
<fx:include source="Book.fxml" />
</Tab>
<Tab fx:id="CReaders" text="Czytelnicy">
<fx:include source="Readers.fxml" />
</Tab>
<Tab fx:id="WLoans" text="Wypożyczenia">
<fx:include source="Borrows.fxml" />
</Tab>
<Tab fx:id="ZReturns" text="Zwroty" >
<fx:include source="Return.fxml" />
</Tab>
<Tab fx:id="Communication" text="Komunikaty" >
<fx:include source="Comunication.fxml" />
</Tab>
</tabs>
</TabPane>
</children>
</VBox>
</children>
</Pane>
As you can see every tab has its own controller. I want to send data from one to another included controller (from Readers.fxml controller to Borrows.fxml controller. My code: READER CONTROLLER
@FXML
void onCRentActionButton(ActionEvent event) throws IOException {
if(CTable.getSelectionModel().getSelectedItem()==null)
{
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Błąd !!!");
alert.setHeaderText("Nie możesz edytować użytkownika, jeśli żadnego"
+ "nie zaznaczyłeś w tabeli!!");
alert.showAndWait();
}
else
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Borrows.fxml"));
loader.load();
logger.info("Kontroller pliku Borrows.fxml to: "+ loader.<BorrowController>getController().getClass());
BorrowController controller = loader.<BorrowController>getController();
ReaderBorrow rb;
int id=CTable.getSelectionModel().getSelectedItem().getId();
rb = SQLController.getInstance().getReaderToBorrow(id);
controller.setReader(rb);
}
BORROW CONTROLLER
public void setReader(ReaderBorrow rb)
{
logger.info("Ustawianie nazwiska: " + rb.getSurname());
this.WSurname.setText(rb.getSurname());
logger.info("Odczyt wartości: " + WSurname.getText());
}
I have a good information that data is send succesfully. And WSurname.getText() method returns a good information. But in my view WSurname TextField is still empty. I think, when I call getController method in ReadersController i get another instance of BorrowController. How can I set data into TextField correct ?
Upvotes: 1
Views: 642
Reputation: 209340
You have the wrong instance of BorrowController
: in onCRentActionButton()
you load Borrows.fxml
again, getting a new copy of the UI, and then you get the controller associated with that new copy. Since that new copy of the UI is never displayed, you're updating something you can't see.
Instead, inject the controllers for the different tabs into the main controller. According to the documentation, you can inject the controller by using the fx:id
for the <fx:include>
with "Controller"
appended.
So in MainController
, add:
@FXML
private BorrowController borrowController ;
@FXML
private ReaderController readerController ;
add fx:id
s to the <fx:include>
s:
<Tab fx:id="CReaders" text="Czytelnicy">
<fx:include fx:id="reader" source="Readers.fxml" />
</Tab>
<Tab fx:id="WLoans" text="Wypożyczenia">
<fx:include fx:id="borrow" source="Borrows.fxml" />
</Tab>
To link the controllers you will need a reference to borrowController
in ReaderController
:
public class ReaderController {
private BorrowController borrowController ;
public void setBorrowController(BorrowController borrowController) {
this.borrowController = borrowController ;
}
// ...
}
which you need to set up in the initialize()
method of your main controller:
public class MainController {
@FXML
private BorrowController borrowController ;
@FXML
private ReaderController readerController ;
// ...
public void initialize() {
readerController.setBorrowController(borrowController);
// ...
}
// ...
}
and then finally you can just do
@FXML
void onCRentActionButton(ActionEvent event) throws IOException {
if(CTable.getSelectionModel().getSelectedItem()==null) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Błąd !!!");
alert.setHeaderText("Nie możesz edytować użytkownika, jeśli żadnego"
+ "nie zaznaczyłeś w tabeli!!");
alert.showAndWait();
} else {
ReaderBorrow rb;
int id=CTable.getSelectionModel().getSelectedItem().getId();
rb = SQLController.getInstance().getReaderToBorrow(id);
borrowController.setReader(rb);
}
}
If you use a MVC approach and keep the state in a model class, you can avoid all the coupling among these controllers.
Upvotes: 1