How can i get an instance of JavaFX controller - javafx

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 ?

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:ids 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.

Related

JavaFX TableView, Labels and Buttons selection is not working and looks and the table looks disabled

This is my first question in this great community. I started a Java FX tutorial on this blog http://code.makery.ch/library/javafx-8-tutorial/ . But I am using IntelliJ IDEA instead of Eclipse. The program compiles successfully but both the TableView in the left and the labels in the right look like they are disabled ( the font color is gray and not black and the table can not be highlighted on mouse hover or click ). So my question is : Why can not I select the Table view ?
TableView, Labels and Buttons looks disabled
package com.melkojji.controller;
import com.melkojji.model.Person;
import com.melkojji.view.PersonOverviewController;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Person> personData = FXCollections.observableArrayList();
public Main() {
this.personData.add(new Person("Mustapha", "HUSAIN"));
this.personData.add(new Person("Mustapha", "EL KOJJI"));
}
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AdressApp");
this.primaryStage.setMinWidth(615);
this.primaryStage.setMinHeight(365);
initRootLayout();
showPersonOverview();
}
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("../view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
} catch (IOException e) {
e.printStackTrace();
}
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
}
public void showPersonOverview() {
try {
// Load person overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("../view/PersonOverview.fxml"));
AnchorPane personOverview = (AnchorPane) loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(personOverview);
// Give the controller access to the main app.
PersonOverviewController controller = loader.getController();
controller.setMain(this);
} catch (IOException e) {
e.printStackTrace();
}
}
public Stage getPrimaryStage() {
return primaryStage;
}
public ObservableList<Person> getPersonData() {
return personData;
}
}
package com.melkojji.view;
import com.melkojji.controller.Main;
import com.melkojji.model.Person;
import com.melkojji.util.DateUtil;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
/**
* Created by melkojji on 1/14/2017.
*/
public class PersonOverviewController {
#FXML
private TableView<Person> personTableView;
#FXML
private TableColumn<Person, String> personFirstNameTableColumn;
#FXML
private TableColumn<Person, String> personLastNameTableColumn;
#FXML
private Label firstNameLabel;
#FXML
private Label lastNameLabel;
#FXML
private Label streetLabel;
#FXML
private Label postalCodeLabel;
#FXML
private Label cityLabel;
#FXML
private Label birthdayLabel;
// Reference to the main application.
private Main main;
/**
* The constructor.
* The constructor is called before the initialize() method.
*/
public PersonOverviewController() {
}
/**
* Initializes the controller class. This method is automatically called
* after the fxml file has been loaded.
*/
#FXML
public void initialize() {
// Initialize the person table with the two columns.
this.personFirstNameTableColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
this.personLastNameTableColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
// Clear person details.
showPersonDetails(null);
// Listen for selection changes and show the person details when changed.
personTableView.getSelectionModel().selectedItemProperty().addListener(((observable, oldValue, newValue) -> showPersonDetails(newValue)));
}
/**
* Is called by the main application to give a reference back to itself.
*
* #param main
*/
public void setMain(Main main) {
this.main = main;
// Add observable list data to the table.
this.personTableView.setItems(main.getPersonData());
}
/**
* Fills all text fields to show details about the person.
* If the specified person is null, all text fields are cleared.
*
* #param person the person or null
*/
public void showPersonDetails(Person person) {
if (person != null) {
// Fill the labels with info from the person object.
firstNameLabel.setText(person.getFirstName());
lastNameLabel.setText(person.getLastName());
streetLabel.setText(person.getStreet());
postalCodeLabel.setText(Integer.toString(person.getPostalCode()));
cityLabel.setText(person.getCity());
birthdayLabel.setText(DateUtil.format(person.getBirthday()));
// birthdayLabel.setText(...);
} else {
// Person is null, remove all the text.
firstNameLabel.setText("");
lastNameLabel.setText("");
streetLabel.setText("");
postalCodeLabel.setText("");
cityLabel.setText("");
birthdayLabel.setText("");
}
}
}
<?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.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="325.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
</BorderPane>
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<AnchorPane disable="true" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.melkojji.view.PersonOverviewController">
<children>
<SplitPane dividerPositions="0.29797979797979796" prefHeight="300.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="160.0" prefWidth="100.0">
<children>
<TableView fx:id="personTableView" editable="true" onSort="#initialize" prefHeight="298.0" prefWidth="175.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="personFirstNameTableColumn" prefWidth="75.0" text="First name" />
<TableColumn fx:id="personLastNameTableColumn" prefWidth="75.0" text="Last name" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children></AnchorPane>
<AnchorPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="160.0" prefWidth="100.0">
<children>
<Label layoutX="14.0" layoutY="14.0" text="Person details :" AnchorPane.leftAnchor="5.0" AnchorPane.topAnchor="5.0" />
<GridPane AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="30.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="First name" />
<Label text="Last name" GridPane.rowIndex="1" />
<Label text="Street" GridPane.rowIndex="2" />
<Label text="City" GridPane.rowIndex="3" />
<Label text="Postal code" GridPane.rowIndex="4" />
<Label text="Birthday" GridPane.rowIndex="5" />
<Label fx:id="firstNameLabel" text="Label" GridPane.columnIndex="1" />
<Label fx:id="lastNameLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label fx:id="streetLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label fx:id="cityLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Label fx:id="postalCodeLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label fx:id="birthdayLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="5" />
</children>
</GridPane>
<ButtonBar prefHeight="40.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0">
<buttons>
<Button mnemonicParsing="false" text="New" />
<Button mnemonicParsing="false" text="Edit" />
<Button mnemonicParsing="false" text="Delete" />
</buttons>
<padding>
<Insets right="5.0" />
</padding>
</ButtonBar>
</children></AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
The disable property will disable a node and all child nodes when set. So, because you have
<AnchorPane disable="true" ..>
the anchor pane and all its subnodes, including the table, are disabled.

Why TableView makes NullPointerException?

I have this controller class for showing the data of the method "getProduct" in a TableView, but I have a NullPointerException related to "tableViewItem.setItems(itemData)". I read some posts about this topic but didn't solve the problem.
package configuradordepc.controller;
//All imports
public class ControladorView implements Initializable {
#FXML private MenuItem mNew, mOpen, mSave, mPrint;
#FXML
private MenuItem mMother, mCPU, mRAM, mGPU, mHardDrive, mCase, mKey, mMouse,
mScreen, mSpeak, mMulti, mDVD, mFan, mPower;
#FXML private Button bSearch, bAdd, bRemove, bClean;
#FXML private TableView tableViewItem;
#FXML private TableColumn<Product, String> nameItemColumn;
#FXML private TableColumn<Product, Double> priceColumn;
#FXML private TableColumn<Product, Integer> availableColumn;
private ObservableList<Product> itemData;
#FXML private TableView tableViewBudget;
#FXML private TableColumn<Product, String> nameBudgetColumn;
#FXML private TableColumn<Product, Double> outTaxColumn;
#FXML private TableColumn<Product, Double> inTaxColumn;
#FXML private TableColumn<Product, Integer> quantityColumn;
private ObservableList<Product> budgetData;
#FXML private TextField tFSearch, tFMin, tFMax;
//Errors from TableView
#Override
public void initialize(URL location, ResourceBundle resources) {
//Items Table
nameItemColumn.setCellValueFactory(
new PropertyValueFactory<>("description"));
priceColumn.setCellValueFactory(
new PropertyValueFactory<>("price"));
availableColumn.setCellValueFactory(
new PropertyValueFactory<>("stock"));
itemData = FXCollections.observableArrayList();
getProduct();
tableViewItem.setItems(itemData);
//Budget Table
nameBudgetColumn.setCellValueFactory(
new PropertyValueFactory<>("description"));
inTaxColumn.setCellValueFactory(
new PropertyValueFactory<>("price"));
budgetData = FXCollections.observableArrayList();
tableViewBudget.setItems(budgetData);
//Bindings Item
final BooleanBinding noItemSelectedI = Bindings.isNull(
tableViewItem.getSelectionModel().selectedItemProperty());
final BooleanBinding emptySearch = Bindings.isEmpty(tFSearch.textProperty());
//Bindings Budget
final BooleanBinding noItemSelectedB = Bindings.isNull(
tableViewBudget.getSelectionModel().selectedItemProperty());
final BooleanBinding emptyBudget = Bindings.isEmpty(tableViewBudget.getItems());
//Disable botones
bSearch.disableProperty().bind(emptySearch);
bAdd.disableProperty().bind(noItemSelectedI);
bRemove.disableProperty().bind(noItemSelectedB);
bClean.disableProperty().bind(emptyBudget);
}
#FXML
private void onSearch(ActionEvent event) {
}
#FXML
private void onAdd(ActionEvent event) {
budgetData.add((Product) tableViewItem.getSelectionModel().selectedItemProperty().getValue());
}
#FXML
private void onDelete(ActionEvent event) {
}
#FXML
private void onClean(ActionEvent event) {
}
//Item Table initialization
public void getProduct() {
//SPEAKER
itemData.add(new Product("Logitech Z213 Multimedia Speakers 2.1", 22.95, 50, SPEAKER));
//HDD
itemData.add(new Product("Seagate Barracuda 7200.14 1TB SATA3", 46.95, 100, HDD));
//HDD_SSD
itemData.add(new Product("Samsung 850 Evo SSD Series 250GB SATA3", 82, 65, HDD_SSD));
//POWER_SUPPLY
itemData.add(new Product("Tacens Mars Gaming 700W", 42.75, 25, POWER_SUPPLY));
//DVD_WRITER
itemData.add(new Product("LG GH24NSD1 Grabadora DVD 24x Negra", 12.95, 55, DVD_WRITER));
//RAM
itemData.add(new Product("G.Skill Ripjaws X DDR3 1600 PC3-12800 8GB 2x4GB CL9", 37.95, 80, RAM));
//SCREEN
itemData.add(new Product("LG 22M47VQ-P 21.5 LED", 115, 10, SCREEN));
//MULTIREADER
itemData.add(new Product("Unotec Lector USB de tarjetas SD/MicroSD", 3.95, 110, MULTIREADER));
//MOTHERBOARD
itemData.add(new Product("Gigabyte GA-H81M-S2H", 49.95, 75, MOTHERBOARD));
//CPU
itemData.add(new Product("Intel Core i5-4460 3.2Ghz Box", 175, 490, CPU));
//MOUSE
itemData.add(new Product("Logitech Wireless Mouse M175 Negro", 12.95, 200, MOUSE));
//GPU
itemData.add(new Product("Gigabyte GeForce GTX 970 Gaming G1 WindForce OC 4GB GDDR5", 354, 480, GPU));
//KEYBOARD
itemData.add(new Product("Nox Krom Kombat Teclado + Ratón", 30.99, 54, KEYBOARD));
//CASE
itemData.add(new Product("NOX Sense 500W + Frontal", 41.95, 65, CASE));
//FAN
itemData.add(new Product("Cooler Master Hyper TX3 EVO CPU Cooler", 21.50, 220, FAN));
}
}
Here is the output:
ant -f C:\\Users\\Marco\\Desktop\\ConfiguradorDePC jfxsa-run
init:
Deleting: C:\Users\Marco\Desktop\ConfiguradorDePC\build\built-jar.properties
deps-jar:
Updating property file: C:\Users\Marco\Desktop\ConfiguradorDePC\build\built-jar.properties
Compiling 2 source files to C:\Users\Marco\Desktop\ConfiguradorDePC\build\classes
Note: C:\Users\Marco\Desktop\ConfiguradorDePC\src\configuradordepc\controller\ControladorView.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
compile:
Deleting directory C:\Users\Marco\Desktop\ConfiguradorDePC\dist\lib
Copying 1 file to C:\Users\Marco\Desktop\ConfiguradorDePC\dist\lib
Detected JavaFX Ant API version 1.3
Launching <fx:jar> task from C:\Program Files\Java\jdk1.8.0_71\jre\..\lib\ant-javafx.jar
Warning: From JDK7u25 the Codebase manifest attribute should be used to restrict JAR repurposing.
Please set manifest.custom.codebase property to override the current default non-secure value '*'.
Launching <fx:deploy> task from C:\Program Files\Java\jdk1.8.0_71\jre\..\lib\ant-javafx.jar
No base JDK. Package will use system JRE.
No base JDK. Package will use system JRE.
jfx-deployment-script:
jfx-deployment:
jar:
Copying 13 files to C:\Users\Marco\Desktop\ConfiguradorDePC\dist\run150788111
jfx-project-run:
Executing C:\Users\Marco\Desktop\ConfiguradorDePC\dist\run150788111\ConfiguradorDePC.jar using platform C:\Program Files\Java\jdk1.8.0_71\jre/bin/java
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException:
file:/C:/Users/Marco/Desktop/ConfiguradorDePC/dist/run150788111/ConfiguradorDePC.jar!/configuradordepc/view/View.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at configuradordepc.ConfiguradorDePC.start(ConfiguradorDePC.java:15)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 more
Caused by: java.lang.NullPointerException
at configuradordepc.controller.ControladorView.initialize(ControladorView.java:75)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 17 more
Exception running application configuradordepc.ConfiguradorDePC
Java Result: 1
Deleting directory C:\Users\Marco\Desktop\ConfiguradorDePC\dist\run150788111
jfxsa-run:
BUILD SUCCESSFUL (total time: 3 seconds)
The FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Accordion?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuButton?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="configuradordepc.controller.ControladorView">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="Archivo">
<items>
<MenuItem fx:id="mNew" mnemonicParsing="false" text="Nuevo" />
<MenuItem fx:id="mOpen" mnemonicParsing="false" text="Abrir" />
<MenuItem fx:id="mSave" mnemonicParsing="false" text="Guardar" />
<MenuItem fx:id="mPrint" mnemonicParsing="false" text="Imprimir" />
</items>
</Menu>
</menus>
</MenuBar>
<Accordion VBox.vgrow="ALWAYS">
<panes>
<TitledPane animated="false" text="Nuevo PC">
<content>
<VBox fx:id="vBox" spacing="10.0">
<children>
<HBox spacing="10.0">
<children>
<TextField fx:id="tFSearch" HBox.hgrow="ALWAYS" />
<Button fx:id="bSearch" mnemonicParsing="false" onAction="#onSearch" text="Buscar" />
</children>
</HBox>
<HBox spacing="10.0" VBox.vgrow="ALWAYS">
<children>
<VBox spacing="10.0">
<children>
<MenuButton maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Categoría">
<items>
<MenuItem fx:id="mMother" mnemonicParsing="false" text="Placas base" />
<MenuItem fx:id="mCPU" mnemonicParsing="false" text="Procesadores" />
<MenuItem fx:id="mRAM" mnemonicParsing="false" text="Memorias RAM" />
<MenuItem fx:id="mGPU" mnemonicParsing="false" text="Tarjetas gráficas" />
<MenuItem fx:id="mHardDrive" mnemonicParsing="false" text="Discos duros" />
<MenuItem fx:id="mCase" mnemonicParsing="false" text="Torres" />
<MenuItem fx:id="mKey" mnemonicParsing="false" text="Teclados" />
<MenuItem fx:id="mMouse" mnemonicParsing="false" text="Ratones" />
<MenuItem fx:id="mScreen" mnemonicParsing="false" text="Monitores" />
<MenuItem fx:id="mSpeak" mnemonicParsing="false" text="Altavoces" />
<MenuItem fx:id="mMulti" mnemonicParsing="false" text="Multilectores" />
<MenuItem fx:id="mDVD" mnemonicParsing="false" text="Grabadoras" />
<MenuItem fx:id="mFan" mnemonicParsing="false" text="Ventiladores" />
<MenuItem fx:id="mPower" mnemonicParsing="false" text="Fuente de alimentación" />
</items>
</MenuButton>
<HBox alignment="CENTER_LEFT">
<children>
<Label prefWidth="87.0" text="Disponibilidad" />
<TextField fx:id="tFAvailable" HBox.hgrow="ALWAYS" />
</children>
</HBox>
<HBox alignment="CENTER_LEFT">
<children>
<Label prefWidth="87.0" text="Precio Mín." />
<TextField fx:id="tFMin" HBox.hgrow="ALWAYS" />
</children>
</HBox>
<HBox alignment="CENTER_LEFT">
<children>
<Label prefWidth="87.0" text="Precio Máx." />
<TextField fx:id="tFMax" HBox.hgrow="ALWAYS" />
</children>
</HBox>
</children>
</VBox>
<VBox alignment="CENTER" spacing="10.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets />
</HBox.margin>
<children>
<TableView VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="nameItemColumn" editable="false" prefWidth="75.0" sortable="false" text="Nombre" />
<TableColumn fx:id="priceColumn" editable="false" prefWidth="75.0" sortable="false" text="Precio" />
<TableColumn fx:id="availableColumn" editable="false" prefWidth="75.0" sortable="false" text="Disponibilidad" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<Button fx:id="bAdd" mnemonicParsing="false" onAction="#onAdd" text="Añadir" />
</children>
</VBox>
<VBox spacing="10.0" HBox.hgrow="ALWAYS">
<children>
<TableView VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="nameBudgetColumn" editable="false" prefWidth="75.0" sortable="false" text="Nombre" />
<TableColumn fx:id="outTaxColumn" editable="false" prefWidth="75.0" sortable="false" text="Sin IVA" />
<TableColumn fx:id="inTaxColumn" editable="false" prefWidth="75.0" sortable="false" text="Con IVA" />
<TableColumn fx:id="quantityColumn" prefWidth="75.0" sortable="false" text="Cantidad" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<HBox alignment="CENTER" spacing="10.0">
<children>
<Button fx:id="bDelete" mnemonicParsing="false" onAction="#onDelete" text="Eliminar" />
<Button fx:id="bClean" mnemonicParsing="false" onAction="#onClean" text="Limpiar" />
</children>
</HBox>
</children>
</VBox>
</children>
</HBox>
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</VBox>
</content>
</TitledPane>
<TitledPane animated="false" text="Configuraciones" />
</panes>
</Accordion>
</children>
</VBox>
You are missing the fx:id attribute on the table. You need
<TableView fx:id="tableViewItem" VBox.vgrow="ALWAYS">
(or just add the fx:id to the table in the "code" section of Scene Builder, if you are using Scene Builder).

Table not updated with new row

I finally got the content into my table (because I've been mastering that mystery out for ages!). Now I'd like to add new Items to the list AND automatically update the table. I thought an ObservableList would do the trick but there seems to be more to it. Can you provide me with a solution?
Controller class:
package controller;
import java.lang.reflect.Constructor;
import db.ItemLijst;
import db.Klant;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import model.Item;
import model.ItemTypes;
public class SchermController {
#FXML
private TableView<Item> tblItems;
#FXML
private TableView<Klant> tblKlanten;
// #FXML
// private TableView<Uitlening> tblUitleningen;
#FXML
private Button btnItemToevoegen;
#FXML
private Button btnKlantToevoegen;
#FXML
private Button btnRegistreer;
#FXML
private ChoiceBox<ItemTypes> cbTypes;
#FXML
private ChoiceBox<Item> cbItems;
#FXML
private ChoiceBox<Klant> cbKlanten;
#FXML
private TextField tfTitel;
#FXML
private TextField tfVoornaam;
#FXML
private TextField tfAchternaam;
#FXML
private TextField tfStraat;
#FXML
private TextField tfNummer;
#FXML
private TextField tfPostcode;
#FXML
private TextField tfGemeente;
#FXML
private TableColumn<Item, String> tcID;
#FXML
private TableColumn<Item, ItemTypes> tcType;
#FXML
private TableColumn<Item, String> tcTitel;
#FXML
private TableColumn<Item, String> tcUitgeleend;
private ObservableList<Item> items = FXCollections.observableArrayList();
#FXML
private void initialize()
{
/*
* ItemLijst is a static object (or object with all static
methods). the CD, Film and Spel classes automatically add their record to
this class. Literally translated it means ItemList. I thought by making this
an ObservableList, the table would be automatically update its records
depending on a change to this variable (ItemLijst.items<Item>)?
*/
items = FXCollections.observableArrayList(ItemLijst.getItems());
tcID.setCellValueFactory(new PropertyValueFactory<Item, String>("ID"));
tcType.setCellValueFactory(new PropertyValueFactory<Item, ItemTypes>("Type"));
tcTitel.setCellValueFactory(new PropertyValueFactory<Item, String>("Titel"));
tcUitgeleend.setCellValueFactory(new PropertyValueFactory<Item, String>("UitgeleendString"));
tblItems.setItems(items);
// Item types
cbTypes.setItems(FXCollections.observableArrayList(ItemTypes.values()));
btnItemToevoegen.setOnAction(e -> {
try {
itemToevoegen();
} catch (Exception e1) {
System.out.println("Probleem: " + e1.getMessage());
}
});
}
/**
* This is the method which I use to add a new item to the CD, Film or Spel
class (which inherits the Item class).
*/
private void itemToevoegen() throws Exception
{
// Validatie
if (cbTypes.getValue() == null ) {
throw new Exception("Je moet een type kiezen");
} else if (tfTitel.getText().trim().isEmpty()) {
throw new Exception("Je moet een titel ingeven");
}
Class<?> klasse = Class.forName("model." + cbTypes.getValue().toString());
Constructor<?> cons = klasse.getConstructor(String.class);
cons.newInstance(tfTitel.getText());
}
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="438.0" prefWidth="743.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.SchermController">
<children>
<TabPane layoutX="-1.0" prefHeight="438.0" prefWidth="744.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab closable="false" text="Items">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="367.0" prefWidth="766.0">
<children>
<TableView fx:id="tblItems" layoutX="14.0" layoutY="14.0" prefHeight="343.0" prefWidth="714.0">
<columns>
<TableColumn fx:id="tcID" prefWidth="303.0" text="Item ID" />
<TableColumn fx:id="tcType" prefWidth="76.0" text="Type" />
<TableColumn fx:id="tcTitel" prefWidth="236.0" text="Titel" />
<TableColumn fx:id="tcUitgeleend" prefWidth="98.0" text="Uitgeleend" />
</columns>
</TableView>
<ChoiceBox fx:id="cbTypes" layoutX="23.0" layoutY="365.0" prefWidth="150.0" />
<TextField fx:id="tfTitel" layoutX="201.0" layoutY="365.0" prefHeight="26.0" prefWidth="352.0" promptText="Titel van item" />
<Button fx:id="btnItemToevoegen" layoutX="592.0" layoutY="365.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="131.0" text="Toevoegen" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab closable="false" text="Klanten">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TableView fx:id="tblKlanten" layoutX="14.0" layoutY="14.0" prefHeight="343.0" prefWidth="714.0">
<columns>
<TableColumn prefWidth="89.0" text="Klant ID" />
<TableColumn prefWidth="87.0" text="Voornaam" />
<TableColumn prefWidth="105.0" text="Achternaam" />
<TableColumn prefWidth="154.0" text="Straat" />
<TableColumn prefWidth="54.0" text="Nr" />
<TableColumn prefWidth="96.0" text="Postcode" />
<TableColumn prefWidth="128.0" text="Gemeente" />
</columns>
</TableView>
<TextField fx:id="tfVoornaam" layoutX="14.0" layoutY="365.0" prefHeight="26.0" prefWidth="105.0" promptText="Voornaam" />
<TextField fx:id="tfAchternaam" layoutX="125.0" layoutY="365.0" prefHeight="26.0" prefWidth="94.0" promptText="Achternaam" />
<TextField fx:id="tfStraat" layoutX="243.0" layoutY="365.0" prefHeight="26.0" prefWidth="150.0" promptText="Straat" />
<TextField fx:id="tfNummer" layoutX="396.0" layoutY="365.0" prefHeight="26.0" prefWidth="32.0" promptText="Nr" />
<TextField fx:id="tfPostcode" layoutX="431.0" layoutY="365.0" prefHeight="26.0" prefWidth="60.0" promptText="Postcode" />
<TextField fx:id="tfGemeente" layoutX="494.0" layoutY="365.0" prefHeight="26.0" prefWidth="130.0" promptText="Gemeente" />
<Button fx:id="btnKlantToevoegen" layoutX="635.0" layoutY="365.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="93.0" text="Toevoegen" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab closable="false" text="Uitleningen">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TableView fx:id="tblUitleningen" layoutX="14.0" layoutY="14.0" prefHeight="343.0" prefWidth="714.0">
<columns>
<TableColumn prefWidth="92.0" text="Klant ID" />
<TableColumn prefWidth="324.0" text="Item ID" />
<TableColumn prefWidth="155.0" text="Start Uitleen" />
<TableColumn prefWidth="142.0" text="Eind Uitleen" />
</columns>
</TableView>
<ChoiceBox fx:id="cbItems" layoutX="15.0" layoutY="364.0" prefHeight="26.0" prefWidth="185.0" />
<ChoiceBox fx:id="cbKlanten" layoutX="244.0" layoutY="364.0" prefHeight="26.0" prefWidth="203.0" />
<Button fx:id="btnRegistreer" layoutX="497.0" layoutY="364.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="229.0" text="Registreer Uitlening" />
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
Looking at the JavaDoc you will find:
public static <E> ObservableList<E> observableArrayList(Collection<? extends E> col)
Creates a new observable array list and adds a content of collection col to it.
So in fact, you are creating a new ObservableList and adding the initial items to it. The simplest solution would be to have ItemsLijst have an ObservableList, and return it in getItems. Then you should only have to do
tblItems.setItems(ItemsLijst.getItems()); // I corrected the class name

Add elements to a Stage from a different controller

I have a MainInterface.fxml, with its own controller MainController in which a button opens a new Stage from NewCrawler.fxml with its associated controller AddCrawlerController.
It looks fine, but i need to add stuff into the MainInterface using the interface NewCrawler .
The goal is adding a new "itemCrawler" each time someone press the "Start Crawling" button in NewCrawler, like the one hardcoded in MainInterface. How Can I do that?
MainController.java
public class MainController {
#FXML private AnchorPane mainPane;
#FXML
public void addCrawlerInstance(String domain) { //TODO dynamically add itemCrawler (Like the one hardcoded in MainInterface
Button b = new Button(domain); //it is only a try to add elements from a different controller
mainPane.getChildren().add(b);
}
#FXML
private void createCrawler () throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("guifxml/NewCrawler.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
}
}
AddCrawlerController.java
public class AddCrawlerController { //ADD Button from Main Interface
#FXML private Button abortButton;
#FXML private Button addCrawlerButton;
#FXML
private void abortCurrentWindow () {
Stage currentStage = (Stage) abortButton.getScene().getWindow();
currentStage.close();
}
#FXML
private void addNewCrawler () throws Exception { //TODO ref. Maincontroller.AddCrawlerInstance
FXMLLoader loader = new FXMLLoader(getClass().getResource("guifxml/MainInterface.fxml"));
Parent root = loader.load();
String d = "prova";
MainController controller = loader.getController();
controller.addCrawlerInstance("prova");
}
}
MainInterface.fxml
<VBox fx:id="mainApp" maxWidth="600.0" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="wsa.gui.MainController">
<children>
<ButtonBar maxWidth="643.0" nodeOrientation="RIGHT_TO_LEFT" prefHeight="40.0" prefWidth="643.0">
<buttons>
<Button alignment="CENTER" mnemonicParsing="false" text="Set Path" />
<Button alignment="CENTER" mnemonicParsing="false" text="Delete" />
<Button alignment="CENTER" mnemonicParsing="false" text="Stop" />
<Button alignment="CENTER" mnemonicParsing="false" text="Start" />
<Button alignment="CENTER" mnemonicParsing="false" onMouseClicked="#createCrawler" text="Add" />
</buttons>
<VBox.margin>
<Insets />
</VBox.margin>
<padding>
<Insets right="5.0" />
</padding>
</ButtonBar>
<AnchorPane fx:id="mainPane" maxHeight="-1.0" maxWidth="-1.0" nodeOrientation="LEFT_TO_RIGHT" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children>
<Separator layoutY="2.0" prefHeight="3.0" prefWidth="645.0" />
<Pane fx:id="itemCrawler" prefHeight="52.0" prefWidth="645.0">
<children>
<Text layoutX="44.0" layoutY="34.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Domain">
<font>
<Font size="20.0" />
</font>
</Text>
<TextField editable="false" layoutX="124.0" layoutY="13.0" prefHeight="25.0" prefWidth="319.0" text="http://www.prova.org" />
<Button alignment="CENTER" layoutX="456.0" layoutY="13.0" mnemonicParsing="false" text="Add URI" />
<Button alignment="CENTER" layoutX="528.0" layoutY="13.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="60.0" text="Explore" />
<CheckBox layoutX="14.0" layoutY="18.0" mnemonicParsing="false" prefHeight="17.0" prefWidth="17.0" />
<Separator layoutY="51.0" nodeOrientation="LEFT_TO_RIGHT" prefHeight="3.0" prefWidth="645.0" />
</children>
</Pane>
</children>
</AnchorPane>
</children>
</VBox>
NewCrawler.fxml
<AnchorPane fx:controller="wsa.gui.AddCrawlerController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TextArea layoutX="119.0" layoutY="89.0" prefHeight="237.0" prefWidth="467.0" />
<Text layoutX="44.0" layoutY="52.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Domain" wrappingWidth="74.13671875">
<font>
<Font size="20.0" />
</font>
</Text>
<TextField layoutX="119.0" layoutY="32.0" prefHeight="25.0" prefWidth="467.0" />
<Text layoutX="44.0" layoutY="111.0" strokeType="OUTSIDE" strokeWidth="0.0" text="URI list" textAlignment="CENTER" wrappingWidth="74.13672208786011">
<font>
<Font size="20.0" />
</font>
</Text>
<Text layoutX="119.0" layoutY="85.0" strokeType="OUTSIDE" strokeWidth="0.0" text="one URI on each line " textAlignment="CENTER" wrappingWidth="467.00000166893005" />
<Button fx:id="addCrawlerButton" layoutX="260.0" layoutY="353.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="115.0" onMouseClicked="#addNewCrawler" text="Start Crawling" />
<Button fx:id="abortButton" layoutX="118.0" layoutY="353.0" mnemonicParsing="false" onMouseClicked="#abortCurrentWindow" prefHeight="25.0" prefWidth="115.0" text="Abort" />
</children>
</AnchorPane>
MainInterface
NewCrawler
What I understand is that you need a dynamic list of itemCrawlers.
Instead of hardcoding a newCrawler, you should use a ListView with a custom CellFactory that constructs custom ListCell to represent itemCrawler.
This tutorial tells you how to do that : http://docs.oracle.com/javafx/2/ui_controls/list-view.htm
I am not 100% sure about this, so correct me if I am wrong.
In the NewCrawler's controller you load the FXML in its constructor. Then you can instantiate the NewCrawler controller and work with it as with any other object inside your MainController.

JavaFX read from text file and display in textarea

I am new to JavaFX and JavaFX Scene Builder and have been researching and trying to figure out for weeks now how to simply read from a text file and display its contents in a textarea. I have a good file reading function in my controller class, but I can't figure out how to display the text file to the text area in the fxml document. I've learned how to click a button and make the file display in the text area, but I want to have the contents in the text area as soon as the GUI loads. If anyone has an idea how to go about doing this, your help will be greatly appreciated!
The last button and text area (towards the end of the FXML document) is the button that prints my text file to netbeans, and the text area in which I would like the text to be dispalyed.
Here is my code:
Controller
import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Scanner;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
public class Screen2Controller implements Initializable , ControlledScreen {
ScreensController myController;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setScreenParent(ScreensController screenParent){
myController = screenParent;
}
#FXML
private void goToScreen1(ActionEvent event){
myController.setScreen(ScreensFramework.screen1ID);
}
#FXML
private void goToProgram(ActionEvent event){
myController.setScreen(ScreensFramework.programID);
}
private void displayText() throws FileNotFoundException {
Scanner s = new Scanner (new File ("EECS.txt")).useDelimiter("\\s+");
while (s.hasNext()) {
if (s.hasNextInt()) { // check if next token is an int
System.out.print(s.nextInt()+" "); // display the found integer
}
else {
System.out.print(s.next()+" "); // else read the next token
}
} //end while
} //end main
} //end screen2controller
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="AnchorPane" prefHeight="650.0" prefWidth="1350.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="departmentdisplay.Screen2Controller">
<children>
<ImageView fitHeight="783.0" fitWidth="1398.0" layoutX="-4.0" layoutY="-80.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#nexus_blue.jpg" />
</image>
</ImageView>
<ImageView fitHeight="149.0" fitWidth="1322.0" layoutX="20.0" layoutY="7.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#departinfohead.png" />
</image>
</ImageView>
<Button layoutX="49.0" layoutY="26.0" mnemonicParsing="false" onAction="#goToScreen1" prefHeight="111.0" prefWidth="121.0">
<graphic>
<ImageView fitHeight="100.0" fitWidth="150.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#backarrow.png" />
</image>
</ImageView>
</graphic></Button>
<SplitPane dividerPositions="0.20765027322404372" layoutX="928.0" layoutY="168.0" orientation="VERTICAL" prefHeight="185.0" prefWidth="415.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="95.0" prefWidth="183.0">
<children>
<Label layoutX="14.0" layoutY="23.0" prefHeight="96.0" prefWidth="158.0" text=" Map" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<font>
<Font name="Arial Black" size="24.0" />
</font>
</Label>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="176.0" prefWidth="158.0">
<children>
<TextArea prefHeight="151.0" prefWidth="242.0" text="Image" wrapText="true" AnchorPane.bottomAnchor="-7.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
</TextArea>
</children>
</AnchorPane>
</items>
</SplitPane>
<SplitPane dividerPositions="0.08057851239669421" layoutX="20.0" layoutY="168.0" orientation="VERTICAL" prefHeight="480.0" prefWidth="898.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label layoutX="369.0" prefHeight="29.0" prefWidth="1062.0" text=" Electrical Engineering & Computer Science" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<font>
<Font name="Arial Black" size="24.0" />
</font>
</Label>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<TextArea fx:id="dinfoTextArea" layoutY="3.0" prefHeight="453.0" prefWidth="896.0"
text="Text file text goes here" wrapText="true"
AnchorPane.bottomAnchor="-14.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="3.0">
</TextArea>
</children>
</AnchorPane>
</items>
</SplitPane>
<SplitPane dividerPositions="0.13286713286713286" layoutX="930.0" layoutY="365.0" orientation="VERTICAL" prefHeight="282.0" prefWidth="413.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="50.0" prefWidth="221.0">
<children>
<Label layoutX="92.0" layoutY="12.0" prefHeight="29.0" prefWidth="263.0" text=" Programs" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<font>
<Font name="Arial Black" size="24.0" />
</font>
</Label>
<Button layoutX="25.0" mnemonicParsing="false" onAction="#displayText" prefHeight="34.0" prefWidth="102.0" text="Go To Programs" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="176.0" prefWidth="158.0">
<children>
<TextArea layoutX="57.0" layoutY="-6.0" prefHeight="339.0" prefWidth="240.0"
text="Lorem ipsum " wrapText="true" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
</TextArea>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
#FXML TextArea YourTextArea; //i think you already know about this
#Override
public void initialize(URL url, ResourceBundle rb) {
try {
Scanner s = new Scanner(new File("EECS.txt")).useDelimiter("\\s+");
while (s.hasNext()) {
if (s.hasNextInt()) { // check if next token is an int
YourTextArea.appendText(s.nextInt() + " "); // display the found integer
} else {
YourTextArea.appendText(s.next() + " "); // else read the next token
}
}
} catch (FileNotFoundException ex) {
System.err.println(ex);
}
}
or you can simply call your button's 'on action' method from initialize(). eg.
#FXML public void displayTextOnButtonClick(){ //suppose this method gets fired when you click button
}
#FXML public void initialize(URL url, ResourceBundle rb) {
displayTextOnButtonClick();
}
Just put the code you wrote inside the displayTextOnButtonClick inside the initialize(). This is what initialize is meant for.
Initialize is called after processing the root node and it adds extra functionality(if defined) and data to the controls present in the fxml.

Resources