I've had a good search and either I'm not using the right terminology or this question hasn't appeared yet. I've been coding in Java for a few years and I've just started playing with Java FX over the last few weeks.
Context:
I'm trying to create an app that is effectively a quiz, but instead of having a new Pane/Tab for each question, I'd like to have them appear side by side.
I have created a questionController for a single question, but I'm unsure of the best way of creating many questionControllers that are all uniquely identifiable by the fx:id's.
I'd like my GUI to be scaleable so the user can select the number of questions displayed per round. I can't seem to work out how to do this without manually setting creating views with different numbers of questionControllers.
Things I've tried
Adding controller gridPane,
Importing the controller in the FXML
But this aren't scaleable as my buttons just become button0 - buttonN
If you require any more information, please let me know.
Question Controller.java
public class QuestionController implements Initializable {
#FXML
private ComboBox<String> chordCombo;
#FXML
private Label questionField;
#FXML
private Button submitButton;
#FXML
private ToggleGroup answerGroup;
#FXML
private RadioButton toggle0, toggle1, toggle2, toggle3, toggle4;
#Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
submitButton.setOnAction((event) -> {
System.out.println("Submit Logic");
});
answerGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) {
if (answerGroup.getSelectedToggle() != null) {
System.out.println(answerGroup.getSelectedToggle().toString());
}
}
});
}
QuestionController.fxml
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="235.0" prefWidth="203.0" styleClass="layout" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="uk.co.temp.QuestionController">
<children>
<BorderPane layoutX="-11.0" layoutY="35.0" prefHeight="235.0" prefWidth="203.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<bottom>
<Button fx:id="submitButton" mnemonicParsing="false" text="Submit" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</Button>
</bottom>
<top>
<Label fx:id="questionField" text="Insert Question Here" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<BorderPane.margin>
<Insets left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</Label>
</top>
<center>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints halignment="CENTER" 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>
<children>
<RadioButton fx:id="toggle0" mnemonicParsing="false" text="Answer A">
<toggleGroup>
<ToggleGroup fx:id="answerGroup" />
</toggleGroup></RadioButton>
<RadioButton fx:id="toggle1" mnemonicParsing="false" text="Answer B" toggleGroup="$answerGroup" GridPane.rowIndex="1" />
<RadioButton fx:id="toggle2" mnemonicParsing="false" text="Answer C" toggleGroup="$answerGroup" GridPane.rowIndex="2" />
<RadioButton fx:id="toggle3" mnemonicParsing="false" text="Answer D" toggleGroup="$answerGroup" GridPane.rowIndex="3" />
<RadioButton fx:id="toggle4" mnemonicParsing="false" text="Answer E" toggleGroup="$answerGroup" GridPane.rowIndex="4" />
</children>
<padding>
<Insets top="10.0" />
</padding>
</GridPane>
</center>
</BorderPane>
</children>
</AnchorPane>
I think you are looking for something like this:
TilePane pane = new TilePane(); // or whatever you are putting the questions in...
int numQuestions = ... ;
QuestionController[] controllers = new QuestionController[numQuestions];
for (int questionNumber = 0 ; questionNumber < numQuestions ; questionNumber++) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/QuestionController.fxml"));
pane.getChildren().add(loader.load());
controllers[questionNumber] = loader.getController();
}
Obviously if the TilePane (or whatever) is defined in another FXML file and injected into another controller, you can put the same code in an event handler or initialize method, as needed, in that controller.
Related
i am trying to navigate to an other fxml file but when i try parent root = loader.load() he catches an exception and throws it back. He prints SYSTEEMFOUT bij laden Fietsenbeheer: but no message with it. laadLedenBeheer is the one that works fine and laadFietsenBeheer doens't.
Here is my main program:
public void laadLedenbeheer() {
try {
String fxmlFile = "/fxml/LedenBeheer.fxml";
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlFile));
// controller instellen
LedenBeheerController controller = new LedenBeheerController(this,createLidservice());
loader.setController(controller);
Parent root = loader.load();
controller.initialiseertabel();
controller.setParent(this);
Scene scene = new Scene(root);
stage.setTitle("Leden beheren");
stage.setScene(scene);
} catch (IOException e) {
System.out.println("SYSTEEMFOUT bij laden ledenbeheer: " + e.getMessage());
}
}
public void laadFietsbeheer() {
try {
String fxmlFile = "/fxml/FietsenBeheer.fxml";
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlFile));
// controller instellen
FietsenBeheerController controller = new FietsenBeheerController(this, createFietsService());
loader.setController(controller);
Parent root = loader.load();
controller.setParent(this);
Scene scene = new Scene(root);
stage.setTitle("Fietsen beheren");
stage.setScene(scene);
} catch (IOException e) {
System.out.println("SYSTEEMFOUT bij laden Fietsenbeheer: " + e.getMessage());
}
}
Here is my fxml file that i am trying to load
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="676.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<center>
<GridPane BorderPane.alignment="CENTER">
<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>
<children>
<BorderPane prefHeight="200.0" prefWidth="200.0">
<center>
<TableView fx:id="tvLeden" prefHeight="506.0" prefWidth="431.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="tcVoornaam" prefWidth="99.0" text="Voornaam">
<cellValueFactory>
<PropertyValueFactory property="voornaam" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="tcNaam" prefWidth="97.0" text="Naam">
<cellValueFactory>
<PropertyValueFactory property="naam" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="tcRijksreg" minWidth="0.0" prefWidth="184.0" text="Rijksregisternummer">
<cellValueFactory>
<PropertyValueFactory property="rijksregisternummer" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
</center>
<bottom>
<FlowPane alignment="CENTER" columnHalignment="CENTER" hgap="20.0" prefHeight="50.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="btnFietsbeheer" mnemonicParsing="false" onAction="#fietsen" text="Fietsbeheer" />
<Button fx:id="btnWijzigenLid" mnemonicParsing="false" onAction="#wijzigenLid" text="Wijzigen" />
<Button fx:id="btnStartdatum" mnemonicParsing="false" onAction="#wijzigenStartdatum" text="Startdatum wijzigen" />
<Button fx:id="btnUitschrijvenLid" mnemonicParsing="false" onAction="#uitschrijvenLid" text="Uitschrijven" />
</children>
</FlowPane>
</bottom>
<GridPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</GridPane.margin>
</BorderPane>
<BorderPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<center>
<FlowPane orientation="VERTICAL" prefHeight="200.0" prefWidth="200.0" vgap="20.0">
<children>
<GridPane hgap="20.0" vgap="5.0">
<children>
<TextField fx:id="tfVoornaam" promptText="Voornaam" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="tfNaam" promptText="Naam" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField fx:id="tfRijksregisternummer" prefHeight="25.0" prefWidth="134.0" promptText="Rijksregisternummer" GridPane.columnIndex="1" />
<TextField fx:id="tfEmail" promptText="Email" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<DatePicker fx:id="dpStartdatum" disable="true" editable="false" promptText="Startdatum" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<CheckBox fx:id="cbUitgeschreven" disable="true" mnemonicParsing="false" text="Uitgeschreven" GridPane.columnIndex="1" GridPane.rowIndex="6" GridPane.valignment="TOP" />
<TextArea fx:id="taOpmerking" prefHeight="200.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="8" GridPane.rowSpan="2" />
<Label text="Rijksregisternummer" />
<Label text="Voornaam" GridPane.rowIndex="1" />
<Label text="Naam" GridPane.rowIndex="2" />
<Label text="E-mail" GridPane.rowIndex="3" />
<Label text="Startdatum" GridPane.rowIndex="5" />
<Label text="Opmerking" GridPane.rowIndex="7" />
</children>
<columnConstraints>
<ColumnConstraints maxWidth="131.0" minWidth="122.0" prefWidth="122.0" />
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" />
<RowConstraints minHeight="10.0" prefHeight="30.0" />
<RowConstraints minHeight="10.0" prefHeight="30.0" />
<RowConstraints minHeight="10.0" prefHeight="30.0" />
<RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
<RowConstraints maxHeight="25.0" minHeight="25.0" prefHeight="25.0" />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</GridPane>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</FlowPane>
</center>
<bottom>
<FlowPane alignment="CENTER" columnHalignment="CENTER" hgap="20.0" prefHeight="50.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="btnAnnuleren" mnemonicParsing="false" onAction="#annuleren" text="Annuleren" />
<Button fx:id="btnOpslaan" mnemonicParsing="false" onAction="#opslaan" text="Ok" />
</children>
</FlowPane>
</bottom>
<GridPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</GridPane.margin>
</BorderPane>
</children>
</GridPane>
</center>
<top>
<FlowPane alignment="CENTER" columnHalignment="CENTER" orientation="VERTICAL" prefHeight="100.0" BorderPane.alignment="CENTER">
<children>
<Label text="Ledenbeheer">
<font>
<Font size="42.0" />
</font>
</Label>
<Label fx:id="laErrorLeden" textFill="RED" />
</children>
</FlowPane>
</top>
</BorderPane>
anyone an idea how to solve this?
I'm newbie in Java FXML. I want to add an item to the TableView in first stage(tableview.fxml) from form I've created in second stage(dodawanie.fxml). Can someone tell me how to do this?
Calling the method AddPersonToTable from DodawanieController causes that ObservableList data is updated, but the TableView not.
TableViewController.java
public class TableViewController {
#FXML public TableView<Person> tableView;
#FXML private TextField firstNameField;
#FXML private TextField lastNameField;
#FXML private TextField emailField;
#FXML
protected void addPerson(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Dodawanie.fxml"));
Stage stage = new Stage();
stage.setTitle("Dodaj ksiazke");
stage.setScene(new Scene(root));
stage.show();
}
public void updateTable(Person person){
ObservableList<Person> data = tableView.getItems();
data.add(person);
tableView.setItems(data);
}
}
DodawanieController.java
public class DodawanieController {
#FXML
private TextField firstNameField;
#FXML
private TextField lastNameField;
#FXML
private TextField emailField;
#FXML
public void AddPersonToTable(ActionEvent actionEvent) throws IOException {
Person person = new Person(firstNameField.getText(), lastNameField.getText(), emailField.getText());
System.out.println(person);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("tableview.fxml"));
loader.load();
TableViewController tableViewController = loader.getController();
tableViewController.updateTable(person);
}
}
tableview.fxml
<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.TableViewController">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<Label style="-fx-font: NORMAL 20 Tahoma;" text="Address Book" GridPane.columnIndex="0" GridPane.rowIndex="0">
</Label>
<TableView fx:id="tableView" GridPane.columnIndex="0" GridPane.rowIndex="1">
<columns>
<TableColumn text="First Name">
<cellValueFactory><PropertyValueFactory property="firstName" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Last Name">
<cellValueFactory><PropertyValueFactory property="lastName" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Email Address">
<cellValueFactory><PropertyValueFactory property="email" />
</cellValueFactory>
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<Person email="jacob.smith#example.com" firstName="Jacob" lastName="Smith" />
<Person email="isabella.johnson#example.com" firstName="Isabella" lastName="Johnson" />
<Person email="ethan.williams#example.com" firstName="Ethan" lastName="Williams" />
<Person email="emma.jones#example.com" firstName="Emma" lastName="Jones" />
<Person email="michael.brown#example.com" firstName="Michael" lastName="Brown" />
</FXCollections>
</items>
</TableView>
<Button alignment="CENTER_RIGHT" onAction="#addPerson" text="Add" GridPane.rowIndex="2" />
<HBox prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="3">
<children>
<TextField fx:id="firstNameField" />
<TextField fx:id="lastNameField" />
<TextField fx:id="emailField" />
</children>
</HBox>
<Button onAction="#addPerson2" mnemonicParsing="false" text="Dodaj" GridPane.rowIndex="4" />
<columnConstraints>
<ColumnConstraints />
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
</GridPane>
Dodawanie.fxml
<GridPane alignment="CENTER" hgap="10.0" prefHeight="400" prefWidth="600" vgap="10.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.DodawanieController">
<columnConstraints>
<ColumnConstraints />
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="10">
<children>
<Label text="First Name" />
<Label text="Last Name" />
<Label text="Email" />
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0" GridPane.columnIndex="1" spacing="10">
<children>
<TextField fx:id="firstNameField" />
<TextField fx:id="lastNameField" />
<TextField fx:id="emailField" />
<Button mnemonicParsing="false" text="Button" onAction="#AddPersonToTable"/>
</children>
</VBox>
</children>
</GridPane>
I want to make a application with a menu on the left and the view on the right. I have different fxml file. 1 main, and multiple for the view.
Right now I load different view but the view on right doesn't his parent.
Main view
<GridPane
xmlns="http://javafx.com/javafx/8.0.112"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="controller.Controller">
<columnConstraints>
<ColumnConstraints percentWidth="30.0" />
<ColumnConstraints percentWidth="70.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<GridPane maxWidth="Infinity" GridPane.columnIndex="0" GridPane.rowIndex="0">
<columnConstraints>
<ColumnConstraints percentWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
<children>
<Button fx:id="devices" maxWidth="Infinity" mnemonicParsing="false" text="Devices" GridPane.columnIndex="0" GridPane.rowIndex="0" />
<Button fx:id="inventory" maxWidth="Infinity" mnemonicParsing="false" text="Inventory" GridPane.columnIndex="0" GridPane.rowIndex="1" />
</children>
</GridPane>
<Pane
fx:id="container"
minWidth="Infinity"
maxWidth="Infinity"
GridPane.hgrow="ALWAYS"
GridPane.vgrow="ALWAYS"
GridPane.columnIndex="1"
GridPane.columnSpan="1"
GridPane.rowIndex="0">
</Pane>
</children>
</GridPane>
Custom view load in container
<GridPane
xmlns="http://javafx.com/javafx/8.0.112"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="controller.DevicesController"
GridPane.hgrow="ALWAYS"
GridPane.vgrow="ALWAYS">
<children>
<TableView
GridPane.columnIndex="0"
GridPane.columnSpan="1"
GridPane.hgrow="ALWAYS"
GridPane.vgrow="ALWAYS"
GridPane.rowIndex="0">
<columns>
<TableColumn text="Devices" />
<TableColumn text="C2" />
</columns>
</TableView>
</children>
</GridPane>
Current form
Controller
public class Controller implements Initializable {
#FXML private Pane container;
#FXML private Button devices;
#FXML private Button inventory;
private HashMap<Views, Node> views;
private enum Views {
DEVICES,
INVENTORY
}
#Override
public void initialize(URL location, ResourceBundle resources) {
try {
views = new HashMap<>();
views.put(Views.DEVICES, FXMLLoader.load(getClass().getResource("../view/" + "view-devices.fxml")));
views.put(Views.INVENTORY, FXMLLoader.load(getClass().getResource("../view/" + "view-inventory.fxml")));
devices.setOnMouseClicked(v -> load(Views.DEVICES));
inventory.setOnMouseClicked(v -> load(Views.INVENTORY));
} catch (IOException e) {
e.printStackTrace();
}
}
public void load(Views view){
if (views.containsKey(view)) {
Node newView = views.get(view);
if (!container.getChildren().contains(newView)) {
container.getChildren().add(newView);
} else {
newView.resize(container.getMaxWidth(), container.getMaxHeight());
newView.toFront();
}
} else {
System.out.println("Error: key not found in map");
}
}
}
I want to the right view to fit the container.
The Pane you are using for the container for the right side of the display performs no layout, so it cannot make the content fill the available space (no matter what settings you use).
Use a BorderPane for the container instead:
<BorderPane
fx:id="container"
GridPane.hgrow="ALWAYS"
GridPane.vgrow="ALWAYS"
GridPane.columnIndex="1"
GridPane.columnSpan="1"
GridPane.rowIndex="0">
</BorderPane>
and then in the controller you can simply set the new content as the center each time:
public class Controller implements Initializable {
#FXML private BorderPane container;
// ...
public void load(Views view){
if (views.containsKey(view)) {
Node newView = views.get(view);
container.setCenter(newView);
} else {
System.out.println("Error: key not found in map");
}
}
}
Hi i have made a javafx app with loading New Tabs inside TabPane.Application running great except the New Tabs Button,TextFields are not working and also the switching of in tabpane is not working.
FXML
<GridPane id="content" alignment="CENTER" prefHeight="310.0" prefWidth="800.0" styleClass="mainParent" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.gvj.sndp.view.controller.HomeController">
<children>
<SplitPane dividerPositions="0.18421052631578946" prefHeight="160.0" prefWidth="200.0" GridPane.rowIndex="2">
<items>
<TreeView fx:id="menuTreeView" prefHeight="273.0" prefWidth="115.0" />
<TabPane fx:id="tabPane" mouseTransparent="true" prefHeight="200.0" prefWidth="200.0" rotateGraphic="true" />
</items>
</SplitPane>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="1">
<children>
<JFXButton buttonType="RAISED" onAction="#addMemberSelect" prefHeight="33.0" prefWidth="37.0" text="AM">
<opaqueInsets>
<Insets />
</opaqueInsets>
<HBox.margin>
<Insets left="5.0" />
</HBox.margin>
</JFXButton>
<JFXButton buttonType="RAISED" onAction="#addSelfHelpSelect" prefHeight="33.0" prefWidth="55.0" text="ASH">
<HBox.margin>
<Insets left="5.0" />
</HBox.margin>
</JFXButton>
<JFXButton onAction="#addOfficeBarrierSelect" prefHeight="35.0" prefWidth="43.0" text="AOB">
<HBox.margin>
<Insets left="5.0" />
</HBox.margin>
</JFXButton>
</children>
</HBox>
<HBox />
</children>
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" minWidth="-1.0" prefWidth="-1.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="35.0" minHeight="22.0" prefHeight="30.0" valignment="CENTER" vgrow="ALWAYS" />
<RowConstraints maxHeight="35.0" minHeight="22.0" prefHeight="22.0" valignment="CENTER" vgrow="ALWAYS" />
<RowConstraints valignment="CENTER" vgrow="ALWAYS" />
</rowConstraints>
</GridPane>
When the user click the button a new tab is create and loaded to the TabPane.
Why isn't not working.What i'm doing wrong??
Controller
#FXML
private TabPane tabPane;
#FXML
private void addMemberSelect() {
App.getInstance().showProgressIndicator(myController);
Task<FXMLLoader> task = new Task<FXMLLoader>() {
#Override
protected FXMLLoader call() throws Exception {
return new FXMLLoader(App.class.getResource(Screens.ADD_MEMBER));
}
#Override
protected void succeeded() {
super.succeeded();
Tab tabA = new Tab("Add Member");
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setFitToHeight(true);
scrollPane.setFitToWidth(true);
try {
scrollPane.setContent(get().load());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
tabA.setContent(scrollPane);
tabPane.getTabs().add(tabA);
App.getInstance().hideProgressIndicator(myController);
}
#Override
protected void failed() {
super.failed();
App.getInstance().hideProgressIndicator(myController);
}
};
new Thread(task).start();
}
I am trying to set the text to different labels using setText() method. I do tried to print the value to check whether the setText receives null or not. But I am able to successfully print the value in the console but why not able to set it to a label is what my question is.
Any suggestions would be helpful to resolve this NullPointerException.
PersonOverviewController.java
package passion.controllers;
import passion.models.Person;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
public class PersonOverviewController{
#FXML
private TableView<Person> personTable;
#FXML
private TableColumn<Person, String> firstNameColumn;
#FXML
private TableColumn<Person, String> lastNameColumn;
#FXML
private Label firstNameLabel;
#FXML
private Label lastNameLabel;
#FXML
private Label streetLabel;
#FXML
private Label postalCodeLabel;
#FXML
private Label cityLabel;
#FXML
private Label birthdayLabel;
public PersonOverviewController() {
}
#FXML
private void initialize() {
// Initialize the person table with the two columns.
firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
try{
//showPersonDetails(null);
//personTable.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> showPersonDetails(newValue));
personTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Person>(){
#Override
public void changed(ObservableValue<? extends Person> observable, Person oldValue, Person newValue) {
System.out.println(newValue);
showPersonDetails(newValue);
}
});
}catch(NullPointerException e){
e.printStackTrace();
}
}
public void showTableViewData(MainApp mainApp) {
personTable.setItems(mainApp.getPersonData());
}
public void showPersonDetails(Person person){
Platform.runLater(new Runnable(){
#Override
public void run() {
if(person != null){
System.out.println(person.getFirstName());
firstNameLabel.setText(person.getFirstName());
System.out.println("test");
lastNameLabel.setText(person.getLastName());
streetLabel.setText(person.getStreet());
postalCodeLabel.setText(Integer.toString(person.getPostalCode()));
cityLabel.setText(person.getCity());
birthdayLabel.setText(person.getBirthday().toString());
}else{
firstNameLabel.setText("");
lastNameLabel.setText("");
streetLabel.setText("");
postalCodeLabel.setText("");
cityLabel.setText("");
birthdayLabel.setText("");
}
}
});
}
}
This is how I am loading the controller from MainApp.java
public void showPersonOverview(){
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("/passion/viewControllers/PersonOverView.fxml"));
AnchorPane personOverview = (AnchorPane)loader.load();
root.setCenter(personOverview);
PersonOverviewController personController = loader.getController();
personController.showTableViewData(this);
} catch (IOException e) {
e.printStackTrace();
}
}
PersonOverview.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="300.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="passion.controllers.PersonOverviewController">
<children>
<SplitPane dividerPositions="0.29797979797979796" layoutX="200.0" layoutY="70.0" 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="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TableView fx:id="personTable" layoutX="-12.0" layoutY="49.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="-0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="firstNameColumn" prefWidth="75.0" text="First Name" />
<TableColumn fx:id="lastNameColumn" prefWidth="75.0" text="Last Name" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" 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 layoutX="34.0" layoutY="38.0" 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">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label text="Last Name" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label text="Street" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label text="City" GridPane.rowIndex="3">
<padding>
<Insets left="5.0" />
</padding>
</Label>
<Label text="Postal Code" GridPane.rowIndex="4">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label text="Birthday" GridPane.rowIndex="5">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label fx:id="firstName" text="Label" GridPane.columnIndex="1">
<padding>
<Insets left="5.0" />
</padding>
</Label>
<Label fx:id="lastName" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label fx:id="street" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label fx:id="city" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label fx:id="postal" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="4">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
<Label fx:id="birthday" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="5">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</Label>
</children>
</GridPane>
<HBox layoutX="229.0" layoutY="244.0" spacing="5.0" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0">
<children>
<Button layoutX="229.0" layoutY="244.0" mnemonicParsing="false" text="New..." />
<Button layoutX="289.0" layoutY="244.0" mnemonicParsing="false" text="Edit..." />
<Button layoutX="351.0" layoutY="244.0" mnemonicParsing="false" text="Delete" />
</children>
</HBox>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
Console:
Person [firstName=StringProperty [value: Satya], lastName=StringProperty [value: Vema], street=StringProperty [value: some street], postalCode=IntegerProperty [value: 1234], city=StringProperty [value: some city], birthday=ObjectProperty [value: 1999-02-21]]
Person [firstName=StringProperty [value: Satya], lastName=StringProperty [value: Vema], street=StringProperty [value: some street], postalCode=IntegerProperty [value: 1234], city=StringProperty [value: some city], birthday=ObjectProperty [value: 1999-02-21]]
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at passion.controllers.PersonOverviewController$2.run(PersonOverviewController.java:69)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/32693051.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/2180324.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/3326003.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
The connection (fx:id to variable name #FXML or #FXML("...")) is missing.
<Label text="First Name" fx:id="firstNameLabel">
Hence the components cannot be set to the FXML generated dialog's actual components.
I think you are missing one part of code.
TextView firstNameLabel = (TextView)findIdById(R.id.yourTextViewIdInLayout);
And you must do that with all your widgets in order not to get a NullPointerException.