How to write Test cases for Javafx Controllers? - maven

I have written this test class for javafx application.
class HelloApplicationTest extends GuiTest {
#Override
protected Parent getRootNode() {
Parent parent = null;
try {
parent = FXMLLoader.load((getResource("hello-view.fxml")));
return parent;
}
catch (IOException ex) {
}
return parent;
}
#Test
void add_button() {
Button add_btn_1=find("#add_btn");
assertFalse(add_btn_1.disableProperty().get());
FxAssert.verifyThat("#add_btn", LabeledMatchers.hasText("Add"));
}
}
I am getting error like this -> java.lang.NoSuchMethodError: 'java.util.Iterator javafx.stage.Window.impl_getWindows()'
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="350.0" prefWidth="666.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.fxml_db.HelloController">
<children>
<Label layoutX="14.0" layoutY="14.0" prefHeight="39.0" prefWidth="295.0" text="Add and View Employee:">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
<Label layoutX="22.0" layoutY="93.0" prefHeight="27.0" prefWidth="124.0" text="Name:" />
<Label layoutX="22.0" layoutY="136.0" prefHeight="27.0" prefWidth="124.0" text="Address:" />
<Label layoutX="22.0" layoutY="181.0" prefHeight="27.0" prefWidth="124.0" text="Age:" />
<TextField fx:id="name" layoutX="106.0" layoutY="94.0" />
<TextField fx:id="address" layoutX="106.0" layoutY="137.0" />
<TextField fx:id="age" layoutX="106.0" layoutY="182.0" />
<Button fx:id="add_btn" layoutX="127.0" layoutY="223.0" mnemonicParsing="false" onAction="#add_details" text="Add" />
<TableView fx:id="table" layoutX="342.0" layoutY="51.0" prefHeight="260.0" prefWidth="305.0">
<columns>
<TableColumn fx:id="idcol" prefWidth="39.33331298828125" text="ID" />
<TableColumn fx:id="namecol" prefWidth="111.3333740234375" text="Name" />
<TableColumn fx:id="addresscol" prefWidth="110.00003051757812" text="Address" />
<TableColumn fx:id="agecol" prefWidth="40.6666259765625" text="Age" />
</columns>
</TableView>
<Button fx:id="connect_db" layoutX="14.0" layoutY="310.0" mnemonicParsing="false" onAction="#connect" text="Connect DB" />
<Button layoutX="200.0" layoutY="223.0" mnemonicParsing="false" onAction="#clear_data" text="Clear" />
</children>
</AnchorPane>
I am not able to fetch the components form the .fxml file. this is my .fxml code

Related

ControlsFX Validation GUI Shift

in my project I am building a JavaFX GUI that looks like this:
Everything works as I imagine.
For the validation of the text fields I would like to use ControlsFX Validation.
When I add these three lines of code and press the button so that the FXML and controller are loaded, the buttons move:
ValidationSupport val = new ValidationSupport();
val.registerValidator(this.firstNameTextfield, Validator.createEmptyValidator("Muss gefüllt sein"));
val.registerValidator(this.lastNameTextfield, Validator.createEmptyValidator("Muss gefüllt sein"));
my GUI behaves completely different. Buttons wiggle back and forth when pressed, like this:
When you leave the button with the mouse it becomes normal again.
Once I delete these three lines of code, the GUI works normally.
Once this error occurs the first time, it does not repeat in the running program.
It always happens only at the first button press.
MainApplication:
public class MainApplication extends Application {
public static void main(String[] args) {
launch();
}
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getClassLoader().getResource("de/bachelorarbeit/gui" +
"/mainwindow/main-application-view.fxml"));
Parent root = fxmlLoader.load();
Scene scene = new Scene(root);
scene.setFill(Color.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
}
MainController:
/**
* controller for main-application-view.fxml
*/
public class MainController implements Initializable {
/**
* gui element
*/
#FXML
private BorderPane borderPane;
/** the instances are saved to save inputs when switching scenes **/
/** instanc of the home **/
private Parent homeRoot;
/** instanc of the home **/
private Parent customerRoot;
/** instanc of the article **/
private Parent articleRoot;
/** instanc of the order **/
private Parent orderRoot;
private double x, y;
#Override
public void initialize(URL location, ResourceBundle resources) {
//set home in the center
this.callHomeUI();
}
/**
* method to load a ui component
* #param ui path of fxml to be loaded
* #return instanc of Parent
*/
private Parent loadUI(String ui) {
Parent root;
try {
FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getClassLoader().getResource(ui));
root = fxmlLoader.load();
} catch (IOException e) {
//TODO Logger
throw new RuntimeException(e);
}
return root;
}
/**
* method to set the home in the center
*/
#FXML
public void callHomeUI(){
if (this.homeRoot == null) {
this.homeRoot = this.loadUI("de/bachelorarbeit/gui/home/home-view.fxml");
}
this.borderPane.setCenter(this.homeRoot);
}
/**
* method to set the home in the customer
*/
#FXML
public void callCustomerUI() {
if (this.customerRoot == null) {
this.customerRoot = this.loadUI("de/bachelorarbeit/gui/customer/customer-view.fxml");
}
this.borderPane.setCenter(this.customerRoot);
}
/**
* method to close the window
*/
#FXML
public void close() {
DataBaseManager.shutDown();
Stage stage = (Stage) this.borderPane.getScene().getWindow();
stage.close();
}
}
CustomerController with the three lines of code:
/**
* controller for customer-view.fxml
*/
public class CustomerController extends CustomerAbstractController implements Initializable {
/** gui elements **/
#FXML
private TextField firstNameTextfield;
#FXML
private TextField lastNameTextfield;
#FXML
private TextField emailTextfield;
#FXML
private DatePicker dateOfBirthPicker;
#FXML
private TextField cityTextfield;
#FXML
private TextField postalCodeTextfield;
#FXML
private TextField streetTextfield;
#FXML
private TextField houseNumberTextfield;
#FXML
private TableView<Customer> customerTableView;
#FXML
private TextField firstNameSearchTextfield;
#FXML
private TextField lastNameSearchTextfield;
#FXML
private TextField emailSearchTextfield;
#Override
public void initialize(URL location, ResourceBundle resources) {
//set listener and build customer table for search
ValidationSupport val = new ValidationSupport();
val.registerValidator(this.firstNameTextfield, Validator.createEmptyValidator("Muss gefüllt sein"));
val.registerValidator(this.lastNameTextfield, Validator.createEmptyValidator("Muss gefüllt sein"));
val.registerValidator(this.emailTextfield, Validator.createEmptyValidator("Muss gefüllt sein"));
}
}
MainApplication FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<BorderPane fx:id="borderPane" prefHeight="720.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.bachelorarbeit.gui.mainwindow.MainController">
<left>
<VBox prefHeight="1080.0" prefWidth="149.0" style="-fx-background-color: #303030;" BorderPane.alignment="CENTER">
<children>
<VBox prefHeight="633.0" prefWidth="149.0">
<children>
<Button mnemonicParsing="false" onAction="#callHomeUI" prefHeight="40.0" prefWidth="200.0" style="-fx-background-color: transparent; -fx-text-fill: #f0f0f0; -fx-font-size: 15;" styleClass="sideButtons" stylesheets="#../../css/styles.css" text="Home">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</Button>
<Button mnemonicParsing="false" onAction="#callCustomerUI" prefHeight="40.0" prefWidth="200.0" style="-fx-background-color: transparent; -fx-text-fill: #f0f0f0; -fx-font-size: 15;" styleClass="sideButtons" stylesheets="#../../css/styles.css" text="Kunde">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</Button>
<Button mnemonicParsing="false" onAction="#callArticleUI" prefHeight="40.0" prefWidth="200.0" style="-fx-background-color: transparent; -fx-text-fill: #f0f0f0; -fx-font-size: 15;" styleClass="sideButtons" stylesheets="#../../css/styles.css" text="Artikel">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</Button>
<Button mnemonicParsing="false" onAction="#callOrderUI" prefHeight="40.0" prefWidth="200.0" style="-fx-background-color: transparent; -fx-text-fill: #f0f0f0; -fx-font-size: 15;" styleClass="sideButtons" stylesheets="#../../css/styles.css" text="Bestellung">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</Button>
</children>
</VBox>
<Button mnemonicParsing="false" onAction="#close" prefHeight="40.0" prefWidth="200.0" style="-fx-background-color: transparent; -fx-text-fill: #f0f0f0; -fx-font-size: 15;" styleClass="sideButtons" stylesheets="#../../css/styles.css" text="Schließen">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</Button>
</children>
</VBox>
</left>
</BorderPane>
Customer FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<TabPane prefHeight="720.0" prefWidth="1080.0" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.bachelorarbeit.gui.customer.CustomerController">
<tabs>
<Tab text="Kunde anlegen">
<content>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<GridPane prefHeight="691.0" prefWidth="771.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="313.857177734375" minWidth="10.0" prefWidth="122.5714111328125" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="556.2857055664062" minWidth="10.0" prefWidth="224.14288330078125" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="556.2857055664062" minWidth="10.0" prefWidth="142.85711669921875" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="556.2857055664062" minWidth="10.0" prefWidth="351.8571472167969" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="10.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="286.4285888671875" minHeight="10.0" prefHeight="116.71429443359375" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Bitte füllen Sie alle Angaben aus, um einen neuen Kunden anlegen zu können." GridPane.columnSpan="4" />
<Label text="Vorname:" GridPane.rowIndex="1" />
<Label text="Nachname:" GridPane.rowIndex="2" />
<Label text="E-Mail:" GridPane.rowIndex="3" />
<TextField fx:id="firstNameTextfield" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="lastNameTextfield" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField fx:id="emailTextfield" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Label text="Geburtstag:" GridPane.rowIndex="4" />
<DatePicker fx:id="dateOfBirthPicker" prefHeight="25.0" prefWidth="250.0" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label text="Stadt:" GridPane.rowIndex="5">
<GridPane.margin>
<Insets />
</GridPane.margin>
</Label>
<TextField fx:id="cityTextfield" GridPane.columnIndex="1" GridPane.rowIndex="5">
<GridPane.margin>
<Insets />
</GridPane.margin>
</TextField>
<Label text="Postleitzahl:" GridPane.columnIndex="2" GridPane.rowIndex="5">
<GridPane.margin>
<Insets left="20.0" />
</GridPane.margin>
</Label>
<TextField fx:id="postalCodeTextfield" maxWidth="100.0" GridPane.columnIndex="3" GridPane.rowIndex="5">
<GridPane.margin>
<Insets right="20.0" />
</GridPane.margin>
</TextField>
<Label text="Strasse:" GridPane.rowIndex="6" />
<TextField fx:id="streetTextfield" GridPane.columnIndex="1" GridPane.rowIndex="6" />
<Label text="Hausnummer:" GridPane.columnIndex="2" GridPane.rowIndex="6">
<GridPane.margin>
<Insets left="20.0" />
</GridPane.margin>
</Label>
<TextField fx:id="houseNumberTextfield" maxWidth="100.0" GridPane.columnIndex="3" GridPane.rowIndex="6" />
<Button mnemonicParsing="false" text="Anlegen" GridPane.rowIndex="8" />
</children>
<padding>
<Insets left="20.0" />
</padding>
</GridPane>
</children>
</AnchorPane>
</content>
</Tab>
<Tab text="Kunde bearbeiten / löschen">
<content>
<GridPane fx:id="bearbeitenGridPane" prefHeight="692.0" prefWidth="1080.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="82.0" minWidth="82.0" prefWidth="82.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="85.0" minWidth="85.0" prefWidth="85.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="85.0" minWidth="85.0" prefWidth="85.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="20.0" minHeight="20.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="637.5714416503906" minHeight="10.0" prefHeight="590.4285583496094" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="An dieser Stelle können Kunden bearbeitet sowie gelöscht werden." GridPane.columnSpan="4">
<GridPane.margin>
<Insets left="20.0" />
</GridPane.margin>
</Label>
<TextField fx:id="firstNameSearchTextfield" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="lastNameSearchTextfield" GridPane.columnIndex="3" GridPane.rowIndex="1" />
<TextField fx:id="emailSearchTextfield" GridPane.columnIndex="5" GridPane.rowIndex="1" />
<Label text="Vorname:" GridPane.halignment="RIGHT" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="20.0" />
</GridPane.margin>
<padding>
<Insets right="10.0" />
</padding>
</Label>
<Label text="Nachname:" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.rowIndex="1">
<padding>
<Insets left="10.0" right="10.0" />
</padding>
</Label>
<Label text="E-Mail:" GridPane.columnIndex="4" GridPane.halignment="RIGHT" GridPane.rowIndex="1">
<padding>
<Insets left="10.0" right="10.0" />
</padding>
</Label>
<Button mnemonicParsing="false" stylesheets="#../../css/styles.css" text="Suchen" GridPane.columnIndex="6" GridPane.halignment="CENTER" GridPane.rowIndex="1">
<GridPane.margin>
<Insets />
</GridPane.margin>
</Button>
<Separator prefWidth="200.0" GridPane.columnSpan="7" GridPane.rowIndex="2" />
<TableView fx:id="customerTableView" stylesheets="#../../css/styles.css" GridPane.columnSpan="7" GridPane.rowIndex="3">
<GridPane.margin>
<Insets bottom="20.0" left="20.0" right="20.0" />
</GridPane.margin>
</TableView>
</children>
</GridPane>
</content>
</Tab>
</tabs>
</TabPane>
Home FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="720.0" prefWidth="1080.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<GridPane prefHeight="720.0" prefWidth="1080.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="195.42855834960938" minWidth="10.0" prefWidth="130.85711669921875" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="299.5714416503906" minWidth="10.0" prefWidth="268.14288330078125" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="130.0" minHeight="130.0" prefHeight="130.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="10.0" minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="10.0" minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="10.0" minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Thema: " GridPane.columnSpan="4" GridPane.rowIndex="4">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Label>
<ImageView fitHeight="127.0" fitWidth="383.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="3" GridPane.halignment="CENTER">
<image>
<Image url="#../images/Ostfalia_LS_RGB_klein.jpg" />
</image>
<GridPane.margin>
<Insets top="20.0" />
</GridPane.margin>
</ImageView>
<Label text="Bachelorarbeit zur Erlangung" GridPane.columnSpan="4" GridPane.valignment="BOTTOM">
<font>
<Font name="System Bold" size="18.0" />
</font>
<GridPane.margin>
<Insets bottom="40.0" left="40.0" />
</GridPane.margin>
</Label>
<Label text="des akademischen Grades Bachelor of Science" GridPane.columnSpan="4" GridPane.valignment="BOTTOM">
<font>
<Font name="System Bold" size="18.0" />
</font>
<GridPane.margin>
<Insets bottom="10.0" left="40.0" />
</GridPane.margin>
</Label>
<Label text="Studiengang: " GridPane.columnSpan="4" GridPane.rowIndex="3">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Label>
<Label text="Hochschule: " GridPane.columnSpan="4" GridPane.rowIndex="2">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Label>
<Label text="Student:" GridPane.columnSpan="2" GridPane.rowIndex="6">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Label>
<Label text="XXX" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.halignment="LEFT" GridPane.rowIndex="7" GridPane.valignment="TOP">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets />
</GridPane.margin>
</Label>
<Label text="Erstgutachter:" GridPane.columnSpan="2" GridPane.rowIndex="9">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Label>
<Label text="Zweitgutachter:" GridPane.columnSpan="2" GridPane.rowIndex="10">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Label>
<Label text="Abgabe:" GridPane.columnSpan="2" GridPane.rowIndex="11">
<font>
<Font size="18.0" />
</font>
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Label>
<Separator prefWidth="200.0" GridPane.columnSpan="4" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="20.0" right="20.0" />
</GridPane.margin>
</Separator>
<Separator prefWidth="200.0" GridPane.columnSpan="4" GridPane.rowIndex="5">
<GridPane.margin>
<Insets left="20.0" right="200.0" />
</GridPane.margin>
</Separator>
<Separator prefWidth="200.0" GridPane.columnSpan="4" GridPane.rowIndex="8">
<GridPane.margin>
<Insets left="20.0" right="200.0" />
</GridPane.margin>
</Separator>
<Label text="Hochschule für angewandte WissenschaftenHochschule Braunschweig/Wolfenbüttel" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="2">
<font>
<Font size="18.0" />
</font>
</Label>
<Label text="Informatik Software Engineering" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="3">
<font>
<Font size="18.0" />
</font>
</Label>
<Label text="Modellbasierte Entwicklung eines Order-To-Cash-Prozesses" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="4">
<font>
<Font size="18.0" />
</font>
</Label>
<Label text="XXXX" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="6">
<font>
<Font size="18.0" />
</font>
</Label>
<Label text="XX" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="9">
<font>
<Font size="18.0" />
</font>
</Label>
<Label text="XX" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="10">
<font>
<Font size="18.0" />
</font>
</Label>
<Label text="XX.07.2022" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="11">
<font>
<Font size="18.0" />
</font>
</Label>
</children>
</GridPane>
</children>
</AnchorPane>
Does anyone have any idea why this happens?
Thanks in advance.
I'll post an answer, even though I have no answer.
I think your issue is a bug. I don't think it is a bug in your code.
It is likely a bug in ControlsFX, or it could be (much less likely) in the JavaFX CSS processor.
I was able to recreate your issue by taking your code and making modifications to allow it to run (e.g. adding imports, removing references to code that is not there, removing references to the missing CSS stylesheet, adding a module-info, adding an opens clause to allow controlsfx to access the scene, etc). To do this I used JavaFX 18 and JDK 18 on OS X (Intel). After that, it could run.
It did not reproduce the shifting button issue you mention.
However, it did produce warning messages in the console:
Jun 07, 2022 5:35:23 PM javafx.scene.CssStyleHelper calculateValue
WARNING: Could not resolve '-fx-text-background-color' while resolving lookups for '-fx-text-fill' from rule '*.label' in stylesheet jar:file:///Users/x/.m2/repository/org/openjfx/javafx-controls/18.0.1/javafx-controls-18.0.1-mac.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss
Jun 07, 2022 5:35:23 PM javafx.scene.CssStyleHelper calculateValue
WARNING: Could not resolve '-fx-text-background-color' while resolving lookups for '-fx-text-fill' from rule '*.label' in stylesheet jar:file:///Users/x/.m2/repository/org/openjfx/javafx-controls/18.0.1/javafx-controls-18.0.1-mac.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss
Jun 07, 2022 5:35:23 PM javafx.scene.CssStyleHelper calculateValue
WARNING: Caught 'java.lang.ClassCastException: class java.lang.String cannot be cast to class javafx.scene.paint.Color (java.lang.String is in module java.base of loader 'bootstrap'; javafx.scene.paint.Color is in module javafx.graphics#18.0.1 of loader 'app')' while converting value for '-fx-background-color' from rule '*.text-input' in stylesheet jar:file:///Users/x/.m2/repository/org/openjfx/javafx-controls/18.0.1/javafx-controls-18.0.1-mac.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss
Jun 07, 2022 5:35:23 PM javafx.scene.CssStyleHelper calculateValue
WARNING: Caught 'java.lang.ClassCastException: class java.lang.String cannot be cast to class javafx.scene.paint.Color (java.lang.String is in module java.base of loader 'bootstrap'; javafx.scene.paint.Color is in module javafx.graphics#18.0.1 of loader 'app')' while converting value for '-fx-highlight-fill' from rule '*.text-input' in stylesheet jar:file:///Users/x/.m2/repository/org/openjfx/javafx-controls/18.0.1/javafx-controls-18.0.1-mac.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss
Jun 07, 2022 5:35:23 PM javafx.scene.CssStyleHelper calculateValue
WARNING: Could not resolve '-fx-text-inner-color' while resolving lookups for '-fx-text-fill' from rule '*.text-input' in stylesheet jar:file:///Users/x/.m2/repository/org/openjfx/javafx-controls/18.0.1/javafx-controls-18.0.1-mac.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss
Jun 07, 2022 5:35:23 PM javafx.scene.CssStyleHelper calculateValue
WARNING: Could not resolve '-fx-text-inner-color' while resolving lookups for '-fx-highlight-text-fill' from rule '*.text-input' in stylesheet jar:file:///Users/x/.m2/repository/org/openjfx/javafx-controls/18.0.1/javafx-controls-18.0.1-mac.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss
Jun 07, 2022 5:35:23 PM javafx.scene.CssStyleHelper calculateValue
The above is just a snippet, hundreds of similar warnings were generated.
These indicate that the CSS system has been fundamentally broken because it is no longer resolving the mandatory looked-up colors it needs to render the scene correctly.
Nevertheless, it appeared to render OK to my screen. However, I wouldn't trust the application to continue working with so many serious warnings logged.
I removed all style values from your scene to see if they were causing some issue, but that didn't help.
I changed the validation code in the customer controller to:
ValidationSupport val = new ValidationSupport();
val.registerValidator(this.firstNameTextfield, Validator.createEmptyValidator("A"));
val.registerValidator(this.lastNameTextfield, Validator.createEmptyValidator("B"));
If you remove all but one of the validators (e.g. only register the validator "A" from the example I provided), then it works. It only fails when there are multiple validators (probably it needs to run a different code path to validate multiple fields).
I reverted the JavaFX version from 18 to 11 and it worked. So this issue is likely because of changes in later versions of JavaFX with which ControlsFX 11 is not compatible (I don't know what that would be). Because of that, I suggest that you file a bug report with ControlsFX (as previously suggested in the comments), you can link back to this question if you file an issue. If you file an issue, it will be more likely to be fixed if you provide a targeted minimal example when doing so (please read and understand the link again), as well as all version info, execution command text, build file, and console logs.
However, due to an unrelated, incompatibility of the earlier JavaFX version with later Mac OS X versions, when I switch to JavaFX 11, all text is garbled, so it is completely unusable, even though it no longer logs CSS processing errors due to adding the validation code.
Interestingly, the CSS warnings are only generated when the customer fxml is loaded into the center of the border pane that was loaded in your original main fxml. If you just set the customer fxml as the root of the scene, the error does not manifest (I don't know why this is). So you can probably work around this issue by a UI redesign (though it would be unfortunate to have to work around an issue like this in such a way).

JavaFX Scene Builder Expand ScrollPane area at runtime when adding components to attached AnchorPane

I haven't been able to find info on this, but I've created a layout in Scene Builder, and I've placed an AnchorPane inside an empty ScrollPane, and added text, a slider, and a label in rows, and then added a button for the user to add a new entry of the above.
Basically a typical preference elicitation UI where the user can also add new entries and specify their own preference values as well.
When pressed, for testing purposes, the button creates a new label, adds it to the AnchorPane, and relocates it to a Y position outside the AnchorPane, and then resizes the AnchorPane so that the new label is included.
The problem that I'm having is that the ScrollPane doesn't adjust and expand the scrollable area to fit the new AnchorPane height, so I can't scroll down to where the new label is visible. In Scene Builder, on the other hand, if I resize the AnchorPane so that it's larger than the ScrollPane, the latter dynamically adjusts the scrollable area, so I'm not sure what the problem is.
Any help is appreciated.
EDIT:
As requested, below is a minimally reproducible version of the project.
Class that loads the FXML and creates the scene
package main;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.TitledPane;
import javafx.stage.Stage;
public class Registration_Page extends Application {
private Stage primaryStage;
private TitledPane mainLayout;
#Override
public void start(Stage primaryStage) throws IOException {
this.primaryStage = primaryStage;
showMainView();
}
private void showMainView() throws IOException {
FXMLLoader loader = new FXMLLoader(Registration_Page.class.getResource("resources/Registration_Page.fxml"));
mainLayout = loader.load();
Scene scene = new Scene(mainLayout);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Class that acts as the button controller, using FXML-defined components.
package main;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
public class ButtonController {
#FXML
private Button plus;
#FXML
private AnchorPane prefValuesAnchorPane;
#FXML
private ScrollPane scrollPane;
#FXML
protected void plusAction(ActionEvent event) {
Label lbl1 = new Label("Hello");
prefValuesAnchorPane.getChildren().add(lbl1);
lbl1.relocate(18, 250);
System.out.println(prefValuesAnchorPane.getHeight());
System.out.println(lbl1.getLayoutY());
if (lbl1.getLayoutY() >= prefValuesAnchorPane.getHeight())
{
prefValuesAnchorPane.resize(prefValuesAnchorPane.getWidth(), lbl1.getLayoutY() + 3);
}
}
}
The FXML document
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" text="User Registration" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.ButtonController">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TextField layoutX="52.0" layoutY="79.0" />
<Text layoutX="14.0" layoutY="96.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name" />
<Text layoutX="14.0" layoutY="130.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Preference Values">
<font>
<Font size="14.0" />
</font>
</Text>
<ScrollPane fx:id="scrollPane" layoutX="14.0" layoutY="137.0" prefHeight="223.0" prefWidth="332.0">
<content>
<AnchorPane fx:id="prefValuesAnchorPane" minHeight="0.0" minWidth="0.0" prefHeight="217.0" prefWidth="329.0">
<children>
<Text layoutX="15.0" layoutY="30.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val1:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="15.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToPixel="false" snapToTicks="true" />
<Label layoutX="280.0" layoutY="12.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Text layoutX="15.0" layoutY="62.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val2:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="50.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToTicks="true" />
<Label layoutX="280.0" layoutY="48.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Text layoutX="15.0" layoutY="97.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val3:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="85.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToTicks="true" />
<Label layoutX="280.0" layoutY="82.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Text layoutX="15.0" layoutY="133.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val4:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="120.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToTicks="true" />
<Label layoutX="280.0" layoutY="118.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Button fx:id="plus" graphicTextGap="1.0" layoutX="289.0" layoutY="153.0" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#plusAction" prefHeight="0.0" prefWidth="30.0" text="+" textAlignment="CENTER" textOverrun="CENTER_ELLIPSIS" AnchorPane.topAnchor="153.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Button>
</children>
</AnchorPane>
</content>
</ScrollPane>
<Button layoutX="532.0" layoutY="335.0" mnemonicParsing="false" text="Next" />
</children></AnchorPane>
</content>
</TitledPane>
The solution to this is to instead have a ScrollPane containing an AnchorPane (as it was), and for every entry added, create an AnchorPane or BorderPane or any other container pane (afaik), and add whatever to it, rather than adding components such as buttons or labels directly onto the original AP that's attached to the SP.

Design JavaFX View with FXML and Java Code

I have created my view for a JavaFX project using FXML. I was wondering if it's possible to add a few more items to the view pragmatically in controller class?
For example, how can I add another set of Text and TextField in my controller file?
FXML
<AnchorPane prefHeight="400.0" prefWidth="228.0">
<children>
<Text layoutY="10.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Selected User:" GridPane.rowIndex="0" />
<Text layoutY="45.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Username :" GridPane.rowIndex="1" />
<TextField fx:id="username" layoutY="55.0" GridPane.rowIndex="2" />
<Text layoutY="100.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Address :" GridPane.rowIndex="3" />
<TextField fx:id="address" layoutY="110.0" GridPane.rowIndex="4" />
<Text layoutY="155.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Web Page :" GridPane.rowIndex="5" />
<TextField fx:id="WP" layoutY="165.0" GridPane.rowIndex="6" />
<Text layoutY="210.0" strokeType="OUTSIDE" strokeWidth="0.0" text="State :" GridPane.rowIndex="7" />
<Text layoutY="265.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Login Name :" GridPane.rowIndex="9" />
<TextField fx:id="login_Name" layoutY="275.0" GridPane.rowIndex="10" />
<Button fx:id="btnSave" layoutX="50.0" layoutY="320.0" mnemonicParsing="false" onAction="#btnSaveClicked" text="Save" />
<Button fx:id="btnSave" layoutX="35.0" layoutY="365.0" mnemonicParsing="false" onAction="#btnDeleteUserClicked" text="Delete User" />
<Button fx:id="btnAddNew" layoutX="30.0" layoutY="410.0" mnemonicParsing="false" onAction="#btnAddeNewClicked" text="Add New User" />
<TextField fx:id="state" layoutX="-2.0" layoutY="222.0" />
</children>
</AnchorPane>
Adding New Nodes in FXML
I would say, you should always add new nodes to the FXML unless you have a very good reason not to. Adding nodes to FXML is as easy as adding an extra line to the existing FXML.
<AnchorPane prefHeight="400.0" prefWidth="228.0">
<children>
...
<Text fx:id="newText"/>
<TextField fx:id="newTextField"/>
</children>
</AnchorPane>
These new nodes will be reflected in the scene graph instantaneously and you can bind them to the controller using their fx:id's.
Adding New Nodes in Controller
First, you should have a fx:id defined for the AnchorPane in order to access it in the controller.
<AnchorPane fx:id="anchorPane" prefHeight="400.0" prefWidth="228.0">
<children>
...
</children>
</AnchorPane>
You can then define the new controls and add them the to AnchorPane in the controller.
public class MyController implements Initializable {
#FXML
private AnchorPane anchorPane;
...
public void intialize() {
...
Text newText = new Text("Some Text");
TextField newTextField = new TextField();
anchorPane.getChildren().addAll(newText, newTextField);
...
}
}

javafx: second stage with fxml doesn't react

I'm trying to use a searchbox in another stage by using fxml for the layout.
It it showing absolutely correct,but it doesn't react to any events.It seems that the elements are not found.
What is wrong with my code?
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
public class SearchBox{
//tabs
#FXML
private static TabPane frepl_tabPane=new TabPane();
#FXML
private static Tab frepl_tabReplace=new Tab();
#FXML
private static Tab frepl_tabSearch=new Tab();
//search
//search Controls
#FXML
private static TextField fr_searchInput=new Textfield();
#FXML
private static Button fr_find=new Button();
private static Stage stage = new Stage();
public static void display(String title) throws IOException {
Parent root = FXMLLoader.load(SearchBox.class.getResource("find_replace.fxml"));
Scene scene = new Scene(root);
stage.setTitle(title);
stage.setScene(scene);
stage.showAndWait();
frepl_tabPane.getSelectionModel().selectedItemProperty().addListener((obs,ov,nv)->{
//no reaction here
stage.setTitle(nv.getText());
System.out.println("pane was tabbed");
});
fr_find.setOnMouseClicked(e ->{
//no reaction here
System.out.println("search");
});
}
To open it i use (inside of the "initialize" function of another FXMLDocumentControler):
btn_search.setOnMouseClicked(e->{
try {
SearchBox.display("search");
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
});
Here is the stack trace(when everything is non static e.g. the class,methods and fields). it appears,when i close the window.
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at SearchBox.display(SearchBox.java:133)
at FXMLDocumentController.lambda$A_table_buttons$22(FXMLDocumentController.java:1309)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="508.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TabPane fx:id="frepl_tabPane" layoutX="-1.0" layoutY="2.0" prefHeight="400.0" prefWidth="508.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab fx:id="frepl_tabSearch" text="Search">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TableView fx:id="fr_Stableview" layoutY="87.0" prefHeight="287.0" prefWidth="508.0">
<columns>
<TableColumn fx:id="fr_Sline" editable="false" prefWidth="75.0" sortable="false" text="Line" />
<TableColumn fx:id="fr_SColumn" editable="false" prefWidth="61.0" sortable="false" text="Column" />
<TableColumn fx:id="fr_SValue" editable="false" prefWidth="371.0" sortable="false" text="Value" />
</columns>
</TableView>
<TextField fx:id="fr_searchInput" layoutX="66.0" layoutY="13.0" prefHeight="25.0" prefWidth="250.0" />
<Label layoutX="3.0" layoutY="17.0" text="Search for:" />
<Button fx:id="fr_find" layoutX="324.0" layoutY="13.0" mnemonicParsing="false" text="Find" />
<Button fx:id="fr_findAll" layoutX="372.0" layoutY="13.0" mnemonicParsing="false" text="Find All" />
<CheckBox fx:id="fr_matchCaseS" layoutX="324.0" layoutY="53.0" mnemonicParsing="false" text="Match case (Aa)" />
<Label fx:id="fr_foundS" layoutX="8.0" layoutY="70.0" text="found: 5" underline="true">
<font>
<Font name="System Bold Italic" size="12.0" />
</font>
</Label>
</children>
</AnchorPane>
</content>
</Tab>
<Tab fx:id="frepl_tabReplace" text="Replace">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TableView fx:id="fr_tableviewR" layoutY="107.0" prefHeight="267.0" prefWidth="508.0">
<columns>
<TableColumn fx:id="fr_lineR" prefWidth="75.0" text="Line" />
<TableColumn fx:id="fr_ColumnR" prefWidth="61.0" text="Column" />
<TableColumn fx:id="fr_ValueR" prefWidth="371.0" text="Value" />
</columns>
</TableView>
<CheckBox fx:id="fr_matchCaseR" layoutX="347.0" layoutY="59.0" mnemonicParsing="false" text="Match case (Aa)" />
<Label layoutX="3.0" layoutY="17.0" text="Search for:" />
<Button fx:id="fr_replace" layoutX="347.0" layoutY="11.0" mnemonicParsing="false" text="Replace" />
<TextField fx:id="fr_replaceInput" layoutX="82.0" layoutY="13.0" prefHeight="25.0" prefWidth="250.0" />
<Button fx:id="fr_replaceAll" layoutX="412.0" layoutY="11.0" mnemonicParsing="false" text="Replace All" />
<TextField fx:id="fr_replaceAllInput" layoutX="82.0" layoutY="55.0" prefHeight="25.0" prefWidth="250.0" />
<Label layoutX="3.0" layoutY="59.0" text="Replace with:" />
<Label fx:id="fr_replacedR" layoutX="3.0" layoutY="90.0" text="replaced: 5" underline="true">
<font>
<Font name="System Bold Italic" size="12.0" />
</font>
</Label>
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</children>
</Pane>

Zk how to reach included .zul page component by id?

I can't reach component by id in the included .zul page. I have one main.zul with a controller and I need to get a component in included zul page through the java controller class, but it returns null.
I know the included method creates new id space but is there any way to get this component?
UPDATE
Here is my code:
the main zul page
<?page title="DealerVizard.zul"?>
<?page id="main" ?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./Dealer" ?>
<zk>
<style src="/resources/css/default.css" />
<window id="Dealer" class="index"
apply="com.i2i.prm.controller.IndexController">
<div class="content" width="100%">
<tabbox id="tb" forward="onSelect=onSelect">
<tabs id="tabs">
<tab id="info" label="INFO" />
<tab id="create" label="CREATE" />
<tab id="edit" label="EDIT" />
<tab id="test" label="TEST PANEL(LIST BOX)" />
</tabs>
<tabpanels>
<tabpanel id="DealerInfo">
<include id="DealerInfoContent"
src="View/Dealer/DealerInfo.zul" />
</tabpanel>
<tabpanel id="DealerCreate">
<include id="DealerCreateContent"
src="View/Dealer/DealerCreate.zul" />
</tabpanel>
<tabpanel id="DealerEdit">
<include id="DealerEditContent"
src="View/Dealer/DealerEdit.zul" />
</tabpanel>
<tabpanel id="PagingListBox">
<include id="PagingListBoxContent" // Included here
src="View/TEST/PagingListBox.zul" />
</tabpanel>
</tabpanels>
</tabbox>
</div>
</window>
</zk>
PagingListBox.zul (Included page)
<?page id="list" ?>
<zk>
<grid width="100%">
<columns>
<column label="" />
</columns>
<rows>
<row>
<listbox id="listModel" width="100%" height="100%"
visible="true" span="true" pagingPosition="top" rows="20"
selectedItem="#{DealerController.selected}"
model="#{DealerController.userList}"
forward="onSelect=//main/Dealer.onSelect">
<auxhead>
<auxheader colspan="1">
<textbox
value="#{DealerController.searchUser.name}" maxlength="9"
id="searchCO_ID" forward="onChanging=//main/Dealer.onSearch"
width="100%">
</textbox>
</auxheader>
<auxheader colspan="1">
<textbox
value="#{DealerController.searchUser.surname}" maxlength="21"
id="searchMSISDN" forward="onChanging=//main/Dealer.onSearch"
width="100%">
</textbox>
</auxheader>
<auxheader colspan="1">
</auxheader>
</auxhead>
<listhead>
<listheader label="Name"
sort="auto(UPPER(name))" />
<listheader label="Surname"
sort="auto(UPPER(surname))" />
<listheader label="Delete ?" />
</listhead>
<listitem self="#{each=USERLIST}">
<listcell>
<label value="#{USERLIST.user.name}" />
<textbox
value="#{DealerController.tmpUser.name}" visible="false" />
</listcell>
<listcell>
<label value="#{USERLIST.user.surname}" />
<textbox
value="#{DealerController.tmpUser.surname}" visible="false" />
</listcell>
<listcell>
<button label="Update"
forward="onClick=//main/Dealer.onUpdate" visible="false" />
<button image="icons/edit-delete.png"
label="Delete" forward="onClick=//main/Dealer.onDelete"
width="100%" disabled="true" />
<button label="Save"
forward="onClick=//main/Dealer.onSave" visible="false" />
<button label="Cancel"
forward="onClick=//main/Dealer.onCancel" visible="false" />
</listcell>
</listitem>
</listbox>
<paging id="pagingData" pageSize="20" />
</row>
</rows>
</grid>
</zk>
IndexCOntroller.java
public class IndexController extends GenericForwardComposer {
private List<User> userList = new ArrayList<User>() ;
AnnotateDataBinder binder;
Tabbox tb;
Window Dealer;
private int pageCount=0;
#Override
public void doAfterCompose(Component comp) throws Exception {
// TODO Auto-generated method stub
super.doAfterCompose(comp);
comp.setVariable(comp.getId() + "Controller", this, true);
binder = (AnnotateDataBinder) Dealer.getVariable("binder", true);
System.out.println(Path.getComponent("//list/listModel"));
}
public IndexController() {
// TODO Auto-generated constructor stub
}
}
Normally I wouldn't recommend using Path.getComponent() way to access other components as your application code becomes tightly coupled with your component structure in your view page.
In your case you simplest way is to use AbstractComponent#getFellow(String compId) method so for eg.
Include inc = (Include) Dealer.getFellow("PagingListBoxContent");
Listbox listModel = (Listbox) inc.getFellow("listModel");
System.out.println(listModel);
So in future even if you insert any other component in your ZUML page before your listbox your code will still work.
UPDATE: BTW there was an interesting blogpost on this very topic on ZK blog recently
if your include have id, you can use dollar sign to get the inner components
<zk>
<include id="inc" src="test.zul />
</zk>
test.zul
<zk>
<label id="lab1" value="test1" />
</zk>
you can use "inc$lab1" get the label in test.zul
You can access any component in any other id space using zscript or java. if it is on the same page, but different window then (component B in window A):
Path.getComponent("/A/B");
if it is on a different page then (component B in window A on page P):
Path.getComponent("//P/A/B");
You can find documentation here: http://books.zkoss.org/wiki/ZK%20Developer%27s%20Reference/UI%20Composing/ID%20Space
You can add in your IndexController.java:
...
private Include DealerInfoContent;
...
this way you can access the included component within the parent composer.
(I would suggest to use camelCase ids for it, though).

Resources