Label in javafx does not change - javafx

This is the code for controller
package Views;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.ResourceBundle;
import javax.imageio.ImageIO;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
public class menuController {
#FXML
private Label eNameLabel;
#FXML
private Button productListButton;
#FXML
private Button employeeListButton;
#FXML
private Button ingredientListButton;
#FXML
private Button addProductButton;
#FXML
private Button addIngreidentButton;
#FXML
private Button addEmployeeButton;
#FXML
private Button LogOutButton;
#FXML
private Label clockLabel;
public void initialize(URL arg0, ResourceBundle arg1) {
clock();
}
public void clock(){
Calendar cal = new GregorianCalendar();
// int day= cal.get(Calendar.DAY_OF_MONTH);
// int month = cal.get(Calendar.MONTH);
// int year = cal.get(Calendar.YEAR);
Date currentDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
// int second = cal.get(Calendar.SECOND);
// int minute = cal.get(Calendar.MINUTE);
// int hour = cal.get(Calendar.HOUR);
this.clockLabel.setText(dateFormat.format(currentDate));
}
}
My label is not changed when I start my program.
I have checked that the label id is given in the scene-builder and everything is connected to its controller or variable.
This is the fxml file that is connected to the controller.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="764.0" prefWidth="901.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Views.menuController">
<children>
<AnchorPane layoutY="2.0" prefHeight="764.0" prefWidth="951.0">
<children>
<HBox prefHeight="100.0" prefWidth="746.0" spacing="20.0">
<children>
<Label lineSpacing="10.0" text="Welcom!">
<font>
<Font size="55.0" />
</font>
</Label>
<Label fx:id="eNameLabel" lineSpacing="10.0" prefHeight="81.0" prefWidth="244.0" text="Label">
<font>
<Font size="55.0" />
</font>
</Label>
</children>
</HBox>
<Button fx:id="LogOutButton" layoutX="768.0" layoutY="704.0" mnemonicParsing="false" onAction="#logOutButtonPushed" prefHeight="46.0" prefWidth="176.0" text="Log Out" />
<Button fx:id="employeeListButton" layoutX="74.0" layoutY="301.0" mnemonicParsing="false" prefHeight="81.0" prefWidth="215.0" text="Employee List" />
<Button fx:id="productListButton" layoutX="368.0" layoutY="301.0" mnemonicParsing="false" prefHeight="81.0" prefWidth="215.0" text="Products List" />
<Button fx:id="ingredientListButton" layoutX="661.0" layoutY="301.0" mnemonicParsing="false" prefHeight="81.0" prefWidth="215.0" text="Ingredients List" />
<Label fx:id="clockLabel" layoutX="74.0" layoutY="710.0" text="Clock" />
<Button fx:id="addEmployeeButton" layoutX="74.0" layoutY="439.0" mnemonicParsing="false" prefHeight="81.0" prefWidth="215.0" text="Add Employee" />
<Button fx:id="addProductButton" layoutX="368.0" layoutY="439.0" mnemonicParsing="false" prefHeight="81.0" prefWidth="215.0" text="Add Products" />
<Button fx:id="addIngreidentButton" layoutX="661.0" layoutY="439.0" mnemonicParsing="false" prefHeight="81.0" prefWidth="215.0" text="Add Ingredients" />
</children>
</AnchorPane>
</children>
</AnchorPane>
When I run the program, the clockLabel stays 'clock' and does not change.
It also does not give me any error.
When I put clock(); in a constructor I made later, it gave me a nullPointerException error at this.clockLabel.setText(dateFormat.format(currentDate));
I tried getting rid of this in this.clockLabel.setText(dateFormat.format(currentDate)); but it didnt work either.

An initialize method taking parameters is only considered, if it's overriding the method from Initializable. In your case the controller class does not implement Initializable, so FXMLLoader only looks for an initialize() method. Either remove the parameters of the method or add implements Initializable to the class.
As for the constructor resulting in a NPE: the injection of the fields happens after the constructor completes in the lifecycle of the controller:
FXMLLoader.load is entered
Parsing the fxml the loader encounters the fx:controller attribute and uses reflection to create a instance of the controller.
The fields are injected based on their fx:ids
The FXMLLoader.load returns.

In addition to Fabian's answer - you can also use the #FXML annotation to make sure the correct method is used:
#FXML
private void initialize() {
...
}

Related

JavaFX ScrollPane and FlowPane properties to resize the FlowPane if columns overfill the ScrollPane width

I have a FlowPane wrapped in a ScrollPane. FlowPane orientation is Vertical, so it will wrap the controls. But I want to set the FlowPane to resize vertically if the columns size is greater than the width of ScrollPane. I've tried a lot of settings, both on ScrollPane and FlowPane but none of them helped me with my wish.
As an image of how I want to do is something like this:
(red contur is ScrollPane, green is FlowPane)
Containers, after the flow pane is populated, with ScrollPane's width more than two columns of controls:
How it works right now, after resizing:
How I want to do after resizing the ScrollPane:
Can this be achieved? What settings I must do to both ScrollPane and FlowPane?
Edit:
Minimal reproduction code:
hello-view.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="424.0" prefWidth="457.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demo.HelloController">
<children>
<AnchorPane layoutX="14.0" layoutY="14.0" prefHeight="399.0" prefWidth="430.0" style="-fx-border-color: #555555;" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" focusTraversable="false" hbarPolicy="NEVER" layoutX="14.0" layoutY="13.0" maxWidth="1.7976931348623157E308" prefHeight="377.0" prefWidth="404.0" style="-fx-border-color: red; -fx-border-width: 2;" AnchorPane.bottomAnchor="7.0" AnchorPane.leftAnchor="13.0" AnchorPane.rightAnchor="12.0" AnchorPane.topAnchor="12.0">
<content>
<FlowPane maxWidth="1.7976931348623157E308" orientation="VERTICAL" prefHeight="363.0" prefWidth="397.0" rowValignment="TOP" style="-fx-border-color: green; -fx-border-width: 2;">
<children>
<Button mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="1">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="12.0" layoutY="12.0" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="2">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="10.0" layoutY="135.0" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="3">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="154.0" layoutY="10.0" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="4">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
</children>
</FlowPane>
</content>
</ScrollPane>
</children>
</AnchorPane>
</children>
</AnchorPane>
HelloController.java:
package com.example.demo;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
#FXML
private Label welcomeText;
#FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
}
HelloApplication.java
package com.example.demo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
HelloApplication.java and HelloController.java are default demo files from starting project in JavaFX.
Conclusion:
Is there a combination of properties for ScrollPane and FlowPane to be able to resize the FlowPane vertically and stop resizing in the right when the control inside tries to move to create a new column (this happens when ScrollPane resize vertically)? I don't want to create those invisible columns in the right, instead grows the FlowPane vertically!
Mention: this could happens in two way
when resize form from the bottom, and the controls from the bottom of the FlowPane will move to the top, and the FlowPane will resize automatically to the right and put the controls in the hidden area of FlowPane, (and)
When you resize form horizontally and there is no more space to move the controls from the right column to the next row, so the FlowPane will not stay anchored to right and to try to create an "invisible" row (or as many as it takes to move needed controls down).
I hope I make it clear as possible.
This answer I found it myself and it works only for FlowPane containing controls with the same size.
Purpose:
Allow user to populate a FlowPane in Vertical orientation, with parent ScrollPane's scrollbars set only to vertical scrollbar visible (when needed) and the FlowPane width to fit ScrollPane's width always.
Starting from a demo project in JavaFX, this is the fxml file which contains definition for the main-view (hello-view.fxml in this case).
hello-view.fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="424.0" prefWidth="457.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demo.HelloController">
<children>
<AnchorPane layoutX="14.0" layoutY="14.0" prefHeight="399.0" prefWidth="430.0" style="-fx-border-color: #555555;" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<ScrollPane fx:id="scrollPane" fitToWidth="true" focusTraversable="false" hbarPolicy="NEVER" layoutX="14.0" layoutY="13.0" maxHeight="1.7976931348623157E308" maxWidth="-Infinity" prefHeight="377.0" prefWidth="404.0" style="-fx-border-color: red; -fx-border-width: 0;" AnchorPane.bottomAnchor="7.0" AnchorPane.leftAnchor="13.0" AnchorPane.rightAnchor="12.0" AnchorPane.topAnchor="12.0">
<content>
<AnchorPane fx:id="ancFlow">
<children>
<FlowPane fx:id="flowPane" orientation="VERTICAL" prefHeight="368.0" prefWidth="396.0" prefWrapLength="10.0" rowValignment="TOP" style="-fx-border-color: green; -fx-border-width: 0;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Button maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="1">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="12.0" layoutY="12.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="2">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="10.0" layoutY="135.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="3">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="154.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="4">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
</children>
</FlowPane>
</children>
</AnchorPane>
</content>
</ScrollPane>
</children>
</AnchorPane>
</children>
</AnchorPane>
HelloController.java file:
package com.example.demo;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.FlowPane;
import java.net.URL;
import java.util.ResourceBundle;
public class HelloController implements Initializable {
private final long buttonWidth = 144;
private final long buttonHeight = 125;
private double columns;
private double rows;
#FXML
private AnchorPane ancFlow;
#FXML
private ScrollPane scrollPane;
#FXML
private FlowPane flowPane;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
// next line was used to see how ancPane is resizing
//ancFlow.setBackground(new Background(new BackgroundFill(Color.rgb(220, 120, 120), new CornerRadii(0), new Insets(0))));
}
public void resizeFlowPaneParent(){
scrollPane.heightProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
if(scrollPane.getHeight() < buttonHeight) return;
double verticalPadding = scrollPane.getPadding().getTop() + scrollPane.getPadding().getTop();
ancFlow.setPrefWidth(scrollPane.getWidth() - (scrollPane.getWidth() - scrollPane.getViewportBounds().getWidth()));
int controls = flowPane.getChildren().size();
rows = Math.floorDiv(newValue.longValue() , buttonHeight + (long)verticalPadding);
if((long)rows == 0) return;
columns = Math.ceilDiv(controls, (long)(rows));
double matchColumns = Math.floorDiv((long)(scrollPane.getWidth()- (scrollPane.getWidth() - scrollPane.getViewportBounds().getWidth())), buttonWidth);
if (columns <= matchColumns) {
if(rows * buttonHeight - (long)verticalPadding <= scrollPane.getHeight() - verticalPadding || (rows * columns * buttonHeight ) > controls * buttonHeight )
{
ancFlow.setPrefHeight(scrollPane.getHeight()-verticalPadding);
}
else
{
ancFlow.setPrefHeight(rows * buttonHeight);
}
}
else
{
double matchRows = Math.ceilDiv(controls, (long)matchColumns);
ancFlow.setPrefHeight(matchRows * buttonHeight);
}
}
});
scrollPane.widthProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
if(newValue.longValue() - (newValue.longValue() - scrollPane.getViewportBounds().getWidth()) < buttonWidth) return;
double verticalPadding = scrollPane.getPadding().getTop() + scrollPane.getPadding().getTop();
ancFlow.setPrefWidth(newValue.longValue() - (newValue.longValue() - scrollPane.getViewportBounds().getWidth()));
int controls = flowPane.getChildren().size();
columns = Math.floorDiv(newValue.longValue() - (long)(newValue.longValue() - scrollPane.getViewportBounds().getWidth()), buttonWidth);
rows = Math.ceilDiv(controls, (long)columns);
if(rows * buttonHeight < scrollPane.getHeight())
{
ancFlow.setPrefHeight(scrollPane.getHeight()-verticalPadding);
}
else
{
ancFlow.setPrefHeight(rows * buttonHeight);
}
}
});
}
}
HelloApplication.java file:
package com.example.demo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
((HelloController)fxmlLoader.getController()).resizeFlowPaneParent();
stage.setWidth(stage.getWidth() + 1);
stage.setHeight(stage.getHeight() + 1);
}
public static void main(String[] args) {
launch();
}
}
The approach was to wrap the FlowPane in a AnchorPane. FlowPane is anchored in AnchorPane to all bounds. The AnchorPane is wrapped in ScrollPane.
In controller I've created a public method in which I added listners to widthProperty() and heightProperty() of ScrollPane to be able to calculate the rows needed for resizing the AnchorPane, based on how many items are in FlowPane and how many columns could be made with the ScrollPane's width. This method was added because size of controls must be read after the scene is displayed, which I've done it in HelloApplication.java main class. In this way listners are added after all items are displayed, and it will be calculated correctly.
Demo:

Javafx: How to print string of array in label using button and textfield?

I am using an IntelliJIdea. I want to display all the numbers that I submitted in Textfield. So I created an ArrayList to put all the numbers I submitted there. However, every time I pressed the button, it does not add all the list, instead only the 1 number I submitted. How can I show all the numbers that I've submitted in Textfield and display it using label. I am using a separate fxml.
enter image description here
sample.fxml:
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.VBox?>
<GridPane fx:controller="com.binarySearch.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="TOP_LEFT" hgap="10" vgap="10">
<Label text="Please enter number" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
<TextField fx:id="inputNumber" GridPane.rowIndex="1" GridPane.columnIndex="0" />
<Button text="Submit" fx:id="submit" GridPane.rowIndex="2" GridPane.columnIndex="0" onAction="#handleSubmitPress"/>
<Button text="Search" fx:id="search" GridPane.rowIndex="3" GridPane.columnIndex="0" onAction="#handleSearchPress" />
<Label text="You input: " GridPane.rowIndex="4" GridPane.columnIndex="0" />
<VBox GridPane.rowIndex="5" GridPane.columnIndex="0" >
<Label fx:id="display" />
</VBox>
</GridPane>
Controller.java
package com.binarySearch;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import java.util.ArrayList;
import java.util.List;
public class Controller {
#FXML
private TextField inputNumber;
#FXML
private Button submit;
#FXML
private Button search;
#FXML
private Label display;
public void handleSubmitPress() {
List<Integer> list = new ArrayList<>();
int num = Integer.parseInt(inputNumber.getText());
list.add(num);
for(int x=0; x<list.size();x++) {
display.setText(list.get(x).toString());
}
}
}
You create a new list in the method itself. This list is initially empty, so after adding the text, it contains a single element. Furthermore using setText replaces the text of the label. It doesn't assign a combination of the strings passed as text; it doesn't add more Labels either.
The first issue could be fixed declaring the list as a field, but the second issue is probably solved best by just adding a new Label to the VBox which may make keeping track of the data in a list unnecessary:
private final List<Integer> list = new ArrayList<>();
#FXML
private VBox vbox;
public void handleSubmitPress() {
int num = Integer.parseInt(inputNumber.getText());
list.add(num);
vbox.getChildren().add(new Label(Integer.toString(num)));
}
<VBox GridPane.rowIndex="5" GridPane.columnIndex="0" fx:id="vbox" />

How to change screens in javafx on detecting radiobutton choice inside a buttonclick listener?

Elaborating my question further, I am developing a question bank in JavaFX. At the home screen, I wish to provide navigation based on radiobutton choice inside a button click.
e.g. If I select a radiobutton choice, and click on the button to proceed ahead, it should direct me to the FXML screen file I have created. To further explain what I am trying to stay, below is the GUI snapshot.
Question Bank GUI Link
I am pasting my code below :
Main HomeScreen FXML File :
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="AnchorPane" prefHeight="548.0" prefWidth="721.0" styleClass="mainFxmlClass" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="controller.HomefxmlController">
<children>
<GridPane alignment="CENTER" gridLinesVisible="false" layoutX="210.0" layoutY="149.0" prefHeight="171.0" prefWidth="373.0" visible="true">
<children>
<RadioButton fx:id="radioBlanks" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#onRadioBlankClick" text="Fill in the Blank" GridPane.columnIndex="0" GridPane.halignment="LEFT" GridPane.rowIndex="0" GridPane.valignment="CENTER" />
<RadioButton fx:id="radioMcq" mnemonicParsing="false" onAction="#onRadioMcqClick" text="MCQ" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowIndex="0" />
<RadioButton fx:id="radioshortNote" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#onRadioSNclick" text="ShortNote" GridPane.columnIndex="0" GridPane.halignment="LEFT" GridPane.rowIndex="1" />
<RadioButton fx:id="radioLongAnswer" mnemonicParsing="false" onAction="#onRadioLNclick" text="LongAnswer" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowIndex="1" />
<RadioButton fx:id="radioScenario" mnemonicParsing="false" onAction="#onRadioScenariocClick" text="Scenario" GridPane.columnIndex="0" GridPane.halignment="LEFT" GridPane.rowIndex="2" />
<RadioButton fx:id="radioTF" mnemonicParsing="false" onAction="#onRadioTFclick" text="True/False" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowIndex="2" />
</children>
<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>
</GridPane>
<Label alignment="CENTER" layoutX="234.0" layoutY="47.0" prefHeight="73.0" prefWidth="211.0" text="Question Bank" textAlignment="CENTER" underline="true" wrapText="false">
<font>
<Font name="Chiller" size="35.0" />
</font>
</Label>
<Button fx:id="btnProceed" layoutX="275.0" layoutY="378.0" mnemonicParsing="false" onAction="#onBtntProceed" prefHeight="48.0" prefWidth="129.0" text="Proceed" textFill="#252285">
<font>
<Font name="Linux Libertine G Regular" size="20.0" />
</font>
</Button>
</children>
<stylesheets>
<URL value="#homefxml.css" />
</stylesheets>
</AnchorPane>
FXML Controller File :
package controller;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.stage.Stage;
/**
* FXML Controller class
*
* #author Vishal
*/
public class HomefxmlController implements Initializable {
#FXML
private RadioButton radioBlanks;
#FXML
private RadioButton radioMcq;
#FXML
private RadioButton radioshortNote;
#FXML
private RadioButton radioLongAnswer;
#FXML
private RadioButton radioScenario;
#FXML
private RadioButton radioTF;
#FXML
private Button btnProceed;
ToggleGroup group;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
toggleGroupAssign();
}
public void toggleGroupAssign() {
group = new ToggleGroup();
radioBlanks.setToggleGroup(group);
radioMcq.setToggleGroup(group);
radioshortNote.setToggleGroup(group);
radioLongAnswer.setToggleGroup(group);
radioScenario.setToggleGroup(group);
radioTF.setToggleGroup(group);
}
#FXML
private void onBtntProceed(ActionEvent event) throws IOException {
// I am selecting just one checkbox at the moment for testing purpose..
if(radioTF.isSelected()){
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/tester.fxml"));
loader.load();
}
}
}
The PROBLEM is that NO ERROR appears at all. No compiletime error, no runtime, nothing ! It just doesn't work !
Kindly help me where exactly I am going wrong ?
loader.load() returns a Node, you don't assign
Take a look at this link
Loading new fxml in the same scene

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

JavaFX (using fxml) and custom class doesn't load

I am attempting to upload my code, but having issues with IntelliJ and gitHub. But the issue lies in the custom class not being found when I'm trying to load the second scene that contains a custom class. Any examples out there that have multiple scenes and custom classes that can lead me down the right path?
I used this sample to start with, and then added my custom class (extends TextField), but as soon as i click the button to go to the second scene it crashes.
http://www.javafxtutorials.com/tutorials/switching-to-different-screens-in-javafx-and-fxml/
controller class
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import sample.numberTextField;
import java.io.IOException;
public class Controller {
#FXML
Label lbl1;
#FXML
Button btn1;
#FXML
Label lbl2;
#FXML
Button btn2;
#FXML
numberTextField txtField1;
#FXML
public void handleButtonClick(ActionEvent event) throws IOException {
Stage stage;
Parent root;
if (event.getSource() == btn1) {
stage = (Stage) btn1.getScene().getWindow();
root = FXMLLoader.load(getClass().getResource("sample2.fxml"));
} else {
stage = (Stage) btn2.getScene().getWindow();
root = FXMLLoader.load(getClass().getResource("sample.fxml"));
}
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import sample.numberTextField?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<AnchorPane prefHeight="150.0" prefWidth="250.0" style="-fx-background-color: blue;">
<children>
<Label fx:id="lbl2" layoutX="81.0" layoutY="29.0" text="This is scene 2" textFill="WHITE" />
<Button fx:id="btn2" layoutX="53.0" layoutY="101.0" mnemonicParsing="false" onAction="#handleButtonClick" text="click to go to scene 1" />
<numberTextField fx:id="txtField1" layoutX="44.0" layoutY="55.0" />
</children>
</AnchorPane>
</children>
</GridPane>
It has been brought to my attention that the naming convention I used on my class file numberTextField needed to be altered to NumberTextField. As soon as I did this, it began working as planned. You have to love case sensitivity, and I don't remember seeing anything anywhere that stated I couldn't do that but all in all I have it working.
Thanks everyone for trying to help.

Resources