JavaFX GridPane inside ScrollPane inside GridPane can't set ScrollPane Growing - javafx

Hi all !
I've got a simple question: I'm using FXML files and I've done this layout:
I am trying to expand the height of the Scrollpane inside the column 1 (row span 3)
With this hierarchy: (top GridPane controller is hightlighted - it is inside a VBox)
And the target ScrollPane closer view:
My problem is that I'm adding dynamically rows to the GridPane inside the ScrollPane (inside the other GridPane container); and I can't add more than 3 columns (size of the Vbox container apparently) but if I remove the scrollpane i can add as many rows that I wan't but rows are disapearing as they are outside of the Vbox/GridPane scope...
Is it possible to do what I wan't (GridPane inside ScrollPane inside mutliple GridPane rows)? I thought it will work "out of the box" but it seems that is really not :-(
Is this because of the ScrollPane Max/Min (I played with all size of containers and/or top-containers -Vbox and ScrollPane- without success...) Or is this because the GridPane parent has max height set and is blocking ScrollPane height growth ?
I have tried this post solution :How to scroll to make a Node within the content of a ScrollPane visible? without any success :-(
Any ideas ? Regards to all !

To answer the question in the middle of the post of "is it possible to do what I want (GridPane inside ScrollPane inside GridPane)" sure! here's the fxml code for it (don't mind the constants, I just threw it together in scene builder):
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<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>
<children><ScrollPane prefHeight="200.0" prefWidth="200.0">
<content><GridPane prefHeight="132.0" prefWidth="297.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<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>
</GridPane>
</content></ScrollPane>
</children>
</GridPane>
the trick to making it so you have a scrollbar with extra rows/columns without making all of the existing rows smaller, is to adjust the height of the innermost gridpane every time you dynamically add a row, this will ensure that the gridpane out-sizes the scrollpane and therefore makes it so the scrollpane 'scrolls'
ex something like (pseudo-code):
onButtonPress{
resizeGridPane(sizeOfRow+paddingBetweenRows);
AddRowInDesiredLocation(location);
}
I think that will give you the desired effect.
EDIT
After noticing your vbox which is inside the scrollpane which is inside the gridpane, you'll have to resize both the vbox and the grid pane appropriately to see the 'scrolling' effect of the scrollpane come around, if you only resize the grid pane, you'll simply get rows which are consecutively smaller and smaller.

Related

My FXML page is not loading, I cannot figure out why

I am having problems figuring out why a page I am trying to load with my JFX FXML loader the page does not load..
With regards to my my FXML load class, my java code complies, but when I execute the code the "More Details page does not load and display when I click on the "More Details" button...here is the code segment that loads the "More Details" page...
// Now set up the stage and place the "post_details_update" on it.
Stage unilink_home_stage = (Stage) btnl_posting_more_details.getScene().getWindow();
unilink_home_stage.close();
// This closes the Login dialog
// now call the post_details_update.fxml
try {
//Parent post_details = FXMLLoader.load( getClass().getResource("/unilink_home/post_details/post_details_update.fxml"));
Parent post_details = FXMLLoader.load( getClass().getResource("/view/unilink_home/post_details/post_details_update.fxml"));
// Note: the path is not relative to the package that this file is in
// but the CLASSPATH from the src/
Stage post_details_stage = new Stage();
post_details_stage.setTitle("Welcome to UniLink");
post_details_stage.setScene(new Scene(post_details));
post_details_stage.show();
} //close the try block
catch(Exception e)
{
//System.out.print(e);
//e.printStackTrace();
System.out.println( e.getMessage() );
}// close the catch block
And the folder structure is...
and the FXML page is.... "post_details_update.fxml":
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.ToolBar?>
<?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.layout.VBox?>
<AnchorPane
fx:id="post_details"
xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/11.0.1"
fx:controller="controller/unilink_home/post/details/unilink_home_post_detailsController"
>
<children>
<VBox prefHeight="401.0" prefWidth="850.0">
<children>
<ToolBar prefHeight="40.0" prefWidth="850.0">
<items>
<Button mnemonicParsing="false" text="Back to Main Window" />
<Label text="Review Post Details">
<padding>
<Insets left="250.0" />
</padding>
</Label>
</items>
</ToolBar>
<GridPane prefHeight="183.0" prefWidth="849.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="474.0" minWidth="10.0" prefWidth="215.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="541.0" minWidth="10.0" prefWidth="101.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="541.0" minWidth="10.0" prefWidth="534.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="144.0" minHeight="10.0" prefHeight="144.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="71.0" minHeight="10.0" prefHeight="39.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ImageView fitHeight="135.0" fitWidth="222.0" pickOnBounds="true" preserveRatio="true">
<GridPane.margin>
<Insets left="50.0" />
</GridPane.margin>
<image>
<Image url="#../../../../images/under_construction.png" />
</image>
</ImageView>
<GridPane prefHeight="131.0" prefWidth="277.0" GridPane.columnIndex="1">
<columnConstraints>
<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="Post ID:" />
<Label layoutX="10.0" layoutY="25.0" text="Title:" GridPane.rowIndex="1" />
<Label layoutX="10.0" layoutY="72.0" text="Description:" GridPane.rowIndex="2" />
<Label layoutX="10.0" layoutY="89.0" text="Creator:" GridPane.rowIndex="3" />
<Label layoutX="10.0" layoutY="99.0" text="Date Created:" GridPane.rowIndex="4" />
<Label layoutX="10.0" layoutY="105.0" text="Status:" GridPane.rowIndex="5" />
</children>
</GridPane>
<GridPane layoutX="225.0" layoutY="10.0" prefHeight="131.0" prefWidth="277.0" GridPane.columnIndex="2">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="47.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="46.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="46.0" 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>
<Button mnemonicParsing="false" text="Upload Image" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="70.0" />
</GridPane.margin>
</Button>
<Button mnemonicParsing="false" text="Close Post" GridPane.columnIndex="2" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="20.0" />
</GridPane.margin>
</Button>
<Button mnemonicParsing="false" text="Delete Post" GridPane.columnIndex="2" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="180.0" />
</GridPane.margin>
</Button>
<Button mnemonicParsing="false" text="Save" GridPane.columnIndex="2" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="350.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
<ListView prefHeight="200.0" prefWidth="200.0" />
</children>
</VBox>
</children>
</AnchorPane>
And the "unilink_home_post_detailsController.java" is just a shell at this stage...
package controller.unilink_home.post.details;
import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
import model.connectionTest;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ChoiceBox;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
//import javafx.event.Event;
//Import the classes for database query
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import model.table_setup_view_postings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.Initializable;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;
import java.net.URL;
import java.util.ResourceBundle;
import model.posting;
public class unilink_home_post_detailsController implements Initializable
{
//database connection related variables,
private String query;
//This is the SQL query string
PreparedStatement ps;
//PreparedStatement ps2;
// This is the prepared statement for the SQL query
private Connection db_connect;
// this is the database connection string for SQL query results
final String DB_NAME = "testDB";
// This is the database name
#FXML // fx:id="post_details"
private AnchorPane post_details; // Value injected by FXMLLoader
//===================================================================================================================
/*
* This method is the class constructor and sets up the controller.
*/
public void unilink_home_post_detailsController()
{
}// close public void unilink_home_post_detailsController()
//===================================================================================================================
/*
* This method will initialiise the UI
*/
//#FXML
#Override
public void initialize(URL location, ResourceBundle resources)
{
}// close public void initialize(URL location, ResourceBundle resources)
}// close public class unilink_home_post_detailsController
With this:
1. The code will compile.
2. When I click the button "More Details"... nothing happens and I am also challenged how I can debug it because in Eclipse with Java JFX the step in/over buttons are greyed out, and it is not showing the variables so I can see the state of these vraibles?
Can anyone help, as I am somewhat new to JFX, and I have read that the FXML loader can be finnicky...
Sincerely.
I found the problem was in the path that I used to point to the controller... somehow I had "/" instead of "." when I made the change it worked. Thank you to those whoresponded.

TextField textProperty Listener across embedded scenes JavaFX

This may be a little convoluted but please bear with me.
I have 3 scenes built using SceneBuilder. The first ("Main") I am using as the parent scene. This scene contains 1 AnchorPane which holds a TabPane and a ToolBar which holds 3 Buttons ("Previous", "Next" and "Close").
The second scene ("PersonaDetails") contains an AnchorPane, a GridPane a number of Textflow (which I am using as field labels) several TextField and DatePicker. This whole scene is embedded into one of the tabs on the TabPane on the first scene ("Main").
The third scene ("Address") is very similar to the second where it contains an AnchorPane, a GridPane a number of Textflow (which I am using as field labels) several TextField and ComboBox. This whole scene is embedded into the other tab on the TabPane on the first scene ("Main").
(I have included the FXML script for each below)
The application will later include additional scenes on additional tab on the TabPane on the first scene ("Main"). This application will form part of larger application and is meant to be a kind of wizard that allows new clients to be registered.
Furthermore, each FXML file and its Controller are in separate packages.
This issue I am having is that I need to add .textProperty() listeners on several of the Textfield so that I can enable, or disable the "Next" Button on the first, or parent, scene ("Main").
I have tried the following code in the MainController class, but it does not work, although it does not generate any errors.
package com.yas.registrationwizard.main;
import com.yas.registrationwizard.personaldetails.PersonalDetailsController;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TabPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class MainController implements Initializable {
#FXML AnchorPane apMain;
#FXML ToolBar tbMain;
#FXML TabPane tpMain;
#FXML Button btnPrevious;
#FXML Button btnNext;
#FXML Button btnClose;
#Override
public void initialize(URL location, ResourceBundle resources) {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("../personaldetails/PersonalDetails.fxml"));
try {
fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
PersonalDetailsController personalDetailsController = fxmlLoader.getController();
personalDetailsController.tfFirstName.textProperty().addListener((obs, oldVal, newVal) -> {
if(newVal.equals("")) {
btnNext.setDisable(true);
} else {
btnNext.setDisable(false);
}
});
}
}
The FXML scripts are as follows:
Main
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="apMain" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.yas.registrationwizard.main.MainController">
<children>
<ToolBar fx:id="tbMain" layoutX="259.0" layoutY="339.0" prefHeight="40.0" prefWidth="200.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="355.0">
<items>
<Pane prefHeight="30.0" prefWidth="370.0" />
<Button fx:id="btnPrevious" maxHeight="25.0" maxWidth="65.0" minHeight="25.0" minWidth="65.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Previous" />
<Button fx:id="btnNext" layoutX="10.0" layoutY="13.0" maxHeight="25.0" maxWidth="65.0" minHeight="25.0" minWidth="65.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Next" />
<Button fx:id="btnClose" layoutX="66.0" layoutY="13.0" maxHeight="25.0" maxWidth="65.0" minHeight="25.0" minWidth="65.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Close" />
</items>
</ToolBar>
<TabPane fx:id="tpMain" layoutX="14.0" layoutY="14.0" prefHeight="335.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<tabs>
<Tab fx:id="tabPersonalDetails" text="Personal Deatils">
<content>
<fx:include fx:id="apPersonalDetails" source="../personaldetails/PersonalDetails.fxml" />
</content></Tab>
<Tab fx:id="tabAddress" text="Address">
<content>
<fx:include fx:id="apAddress" source="../address/Address.fxml" />
</content></Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
Address
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="apAddress" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="325.0" prefWidth="590.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.yas.registrationwizard.address.AddressController">
<children>
<GridPane fx:id="gpAddress" layoutX="195.0" layoutY="103.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="103.0" minWidth="3.0" prefWidth="82.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="219.0" minWidth="10.0" prefWidth="155.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="422.0" minWidth="10.0" prefWidth="274.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="93.0" minWidth="0.0" prefWidth="78.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 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 alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="295.0" text="House Name / Number:" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin></Label>
<Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="246.0" text="Address Line 1:" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin></Label>
<Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="239.0" text="Address Line 2:" GridPane.columnIndex="1" GridPane.rowIndex="4">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin></Label>
<Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="234.0" text="Town / City:" GridPane.columnIndex="1" GridPane.rowIndex="5">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin></Label>
<Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="237.0" text="Region / County:" GridPane.columnIndex="1" GridPane.rowIndex="6">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin></Label>
<TextField fx:id="tfHseNameNum" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<TextField fx:id="tfAddLine1" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<TextField fx:id="tfAddLine2" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<TextField fx:id="tfTownCity" GridPane.columnIndex="2" GridPane.rowIndex="5" />
<TextField fx:id="tfRegionCounty" GridPane.columnIndex="2" GridPane.rowIndex="6" />
<Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="234.0" text="Postcode:" GridPane.columnIndex="1" GridPane.rowIndex="7">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin>
</Label>
<TextField fx:id="tfPostcode" GridPane.columnIndex="2" GridPane.rowIndex="7" />
<Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="234.0" text="Country:" GridPane.columnIndex="1" GridPane.rowIndex="8">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin>
</Label>
<ComboBox fx:id="cboCountry" prefHeight="25.0" prefWidth="294.0" GridPane.columnIndex="2" GridPane.rowIndex="8" />
</children>
</GridPane>
</children>
</AnchorPane>
PersonDetails
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="apPersonalDetails" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="325.0" prefWidth="590.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.yas.registrationwizard.personaldetails.PersonalDetailsController">
<children>
<GridPane fx:id="gpPersonalDetails" layoutX="195.0" layoutY="103.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="37.0" prefWidth="37.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="236.0" minWidth="10.0" prefWidth="236.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="422.0" minWidth="10.0" prefWidth="277.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="38.0" prefWidth="41.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 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>
<TextField fx:id="tfFirstName" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<TextField fx:id="tfMidNameInit" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<TextField fx:id="tfLastName" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<DatePicker fx:id="dpDoB" prefHeight="25.0" prefWidth="365.0" GridPane.columnIndex="2" GridPane.rowIndex="5" />
<TextField fx:id="tfNatInsNum" GridPane.columnIndex="2" GridPane.rowIndex="6" />
<TextFlow fx:id="tflFirstName" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets right="10.0" top="10.0" />
</GridPane.margin></TextFlow>
<TextFlow fx:id="tflLastName" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="4">
<padding>
<Insets right="10.0" top="10.0" />
</padding>
</TextFlow>
<TextFlow fx:id="tflDoB" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="5">
<padding>
<Insets right="10.0" top="10.0" />
</padding>
</TextFlow>
<TextFlow fx:id="tflNatInsNum" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="6">
<padding>
<Insets right="10.0" top="10.0" />
</padding>
</TextFlow>
<TextFlow fx:id="tflMidNameInit" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="3">
<padding>
<Insets right="10.0" top="10.0" />
</padding>
</TextFlow>
</children>
</GridPane>
</children>
</AnchorPane>
The folder structure for the project is shown in the image below:
Firstly, I am bit confused with the wording "scene" in the question. I believe what you mentioned in the question is about handling the nodes, because all the fxmls are handled in the same Scene/Stage.
Anyway, the main problem of the issue lies in the MainController initialize method. You are loading a new instance of PersonalDetailsController and working on it, instead of working on the controller that is actually binded to MainController.
When including fxmls in an fxml, the sub fxml's controller will be already injected to the main fxml controller. So I believe changing your MainController code as below should work as expected.
Update: Sorry for a bit misleading info. The correct thing is, you need to inject the controller with a certain naming convention. If you are including an fxml using fx:include, to get the controller you need to inject with a naming convention <fxid>Controller and <fxid> for getting the node reference.
So considering your example, for the given fx:include line:
<fx:include fx:id="apPersonalDetails" source="../personaldetails/PersonalDetails.fxml" />
your code in MainController should be:
// For controller reference
#FXML PersonalDetailsController apPersonalDetailsController;
// For Node reference
#FXML AnchorPane apPersonalDetails;
So the updated code will be as below:
import com.yas.registrationwizard.personaldetails.PersonalDetailsController;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TabPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class MainController implements Initializable {
#FXML AnchorPane apMain;
#FXML ToolBar tbMain;
#FXML TabPane tpMain;
#FXML Button btnPrevious;
#FXML Button btnNext;
#FXML Button btnClose;
#FXML PersonalDetailsController apPersonalDetailsController;
#Override
public void initialize(URL location, ResourceBundle resources) {
apPersonalDetailsController.tfFirstName.textProperty().addListener((obs, oldVal, newVal) -> {
if(newVal.equals("")) {
btnNext.setDisable(true);
} else {
btnNext.setDisable(false);
}
});
}
}

Stretch Tableview to content size

I have a TableView inside a JavaFX ScrollPane, together with some other Views parallel to it. Something like this here:
<ScrollPane maxHeight="Infinity" maxWidth="Infinity" VBox.vgrow="ALWAYS">
<GridPane maxHeight="Infinity" maxWidth="Infinity" prefWidth="1100">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="Infinity" minWidth="0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="Infinity" minWidth="0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="Infinity" minHeight="10.0" vgrow="ALWAYS" />
</rowConstraints>
<VBox GridPane.columnIndex="1" GridPane.rowSpan="2147483647">
<PieChart fx:id="amountPerState" legendVisible="false" minHeight="300" minWidth="300" />
<PieChart fx:id="amountPerComponent" legendVisible="false" minHeight="300" minWidth="300" />
</VBox>
<TableView fx:id="componentTable" maxHeight="Infinity" maxWidth="Infinity" GridPane.rowIndex="6">
<columns>
...
</columns>
</TableView>
</GridPane>
</ScrollPane>
Now this double scrolling from the ScrollPane and the TableView is ackward. When I try to scroll inside the TableView the ScrollPane also scrolls. I would love to have the TableView go as high as necessary for it's content, so that there is only the scrolling of the ScrollPane. Any Idea how I can do that? Or other ideas?
Edit: For extra clarification, I assume the TableView should have prefered size so high that all it's content is shown without any scrolling necessary. Then there are probably no scroll bars, or I can just not show them with the policy. This is how I think you would achieve this, but I don't know how to figure out the tables content hight to make it it's preferred size.
I think it will be a bit worse in performance, since TableView has this row reusing, but I know that there are not to many rows in the TableView, so that there will be no performance problems.
Edit: Both the charts and the table are to big for the windows, so they all need to be in the ScrollPane

java.lang.reflect.InvocationTargetException when i try to change the label's text value

Here is a simple label project for javafx using fxml with netbeans.
The problem is, when I use
StartFomulars.setText("abc");
It just gets an exception given below.
Here is the code for main,
package main;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Start extends Application {
#Override
public void start(Stage stage) throws Exception {
Prove Controller = new Prove();
Controller.launchController(stage);
}
public static void main(String[] args) {
launch(args);
}
}
The fxml,
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0" prefWidth="1080.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
<children>
<GridPane layoutX="0.0" layoutY="0.0" prefHeight="720.0" prefWidth="1080.0">
<children>
<GridPane GridPane.columnIndex="0" GridPane.rowIndex="0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<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>
</GridPane>
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="1">
<children>
<GridPane GridPane.columnIndex="0" GridPane.rowIndex="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>
</GridPane>
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="282.0" minHeight="10.0" prefHeight="282.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="281.0" minHeight="10.0" prefHeight="281.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
<GridPane GridPane.columnIndex="0" GridPane.rowIndex="1">
<children>
<Label text="Given: " GridPane.columnIndex="0" GridPane.rowIndex="0" />
<Label text="Prove: " GridPane.columnIndex="0" GridPane.rowIndex="1" />
<Label text="Goal: " GridPane.columnIndex="0" GridPane.rowIndex="2" />
<Label fx:id="StartFomulars" text="StartFomulars" GridPane.columnIndex="1" GridPane.rowIndex="0" />
<Label fx:id="GoalFomular" text="GoalFomular" GridPane.columnIndex="1" GridPane.rowIndex="2" />
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="457.0" minWidth="10.0" prefWidth="125.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="802.0" minWidth="10.0" prefWidth="790.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="188.0" minHeight="10.0" prefHeight="156.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="364.0" minHeight="10.0" prefHeight="364.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="186.0" minHeight="10.0" prefHeight="43.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="915.0" minWidth="10.0" prefWidth="915.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="539.0" minWidth="10.0" prefWidth="165.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="359.0" minHeight="10.0" prefHeight="157.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="582.0" minHeight="10.0" prefHeight="563.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</children>
</AnchorPane>
Here is the code for controller,
package main;
import ast.LogicStatement;
import java.io.IOException;
import java.util.List;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
/**
*
* #author zl2511
*/
public class Prove {
private Parent parent;
private Scene scene;
private Stage stage;
private List<LogicStatement> startStatements;
private LogicStatement goalStatement;
#FXML
private Label StartFomulars, GoalFomular;
public Prove() throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Prove.fxml"));
//fxmlLoader.setController(this);
try {
parent = (Parent) fxmlLoader.load();
scene = new Scene(parent);
} catch (IOException e) {
}
StartFomulars.setText("abc");
}
public void launchController(Stage stage) {
this.stage = stage;
stage.setTitle("start");
stage.setScene(scene);
stage.setResizable(true);
stage.hide();
stage.show();
}
public void redirectprove(Stage stage, List<LogicStatement> startFormulas, LogicStatement goalFormula) {
this.startStatements = startFormulas;
this.goalStatement = goalFormula;
stage.setScene(scene);
stage.hide();
stage.show();
}
}
Here is the exception,
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:367)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:305)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:894)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:56)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:158)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
Your structure is pretty unusual. It's more normal to structure an Application class, FXML file, and controller as shown in the tutorial.
As you have things set up, there is no connection between your controller class and the FXML. So the fields annotated #FXML never get initialized.
The way this is intended to work, is that the FXMLLoader's load(...) method will parse the FXML file. If there is a controller set on the loader, then any elements with a fx:id attribute defined will be injected into matching #FXML annotated fields in the controller.
There are basically two ways of setting a controller on the FXMLLoader. The first is to have a fx:controller attribute defined on the root element of the FXML file. This will cause the FXML loader to create a new instance of the specified class, and use that as its controller. Note this won't work in your case, because you want the controller to be the Prove instance you have already created, not a new instance of the Prove class.
The second way is to create an FXMLLoader instance (instead of relying on the static FXMLLoader.load(URL) method you are currently using), and call setController(...) on that instance. So (I think) uncommenting the
//fxmlLoader.setController(this);
line will get this to work.
You may need to separate the declarations of the fields too, i.e.:
#FXML
private Label StartFomulars ;
#FXML
private Label GoalFomular;
(It might work without that change, I've never tried it the way you have it.)
You should probably also take out the try {...} catch (...) {...} structure in the constructor for Prove (since you declare it throws IOException anyway), or at least do something in the catch block. Right now if an exception occurs loading the FXML you won't know about it, and you will just plough ahead and try and set the text of the label.

How to merge cells in JavaFX Scene builder?

I have a gridpane looks like a KeyBoard, and I need to merge some cells to put a "Space" button.. But I cant find any option in the settings of the gridpane which would solve my problem.. Does anyone have an idea how I could achieve it?
Setup your Grid with items in it
Create a GridPane.
Place nodes in the grid.
Select a node in the grid.
It is very, very important that a node in the grid be selected at this stage . . .
After that either:
A. Use the Menu Items
Choose Modify | GridPane
Choose any of
Increase Row Span
Decrease Row Span
Increase Column Span
Decrease Column Span
B. Use the Layout Panel
Modify the Row Span or the Column Span values.
Layout Notes
To really get something to fill up the grid and span rows or columns in the way you want, you may need to modify other layout parameters of the node or it's grid constraints in the layout panel. For example a Button won't normally grow beyond it's preferred size, so set it's max height and width to MAX_VALUE. Another example is to have a Label centered across two columns, set its Hgrow to ALWAYS and its Halignment to CENTER.
Sample Screenshot
There are menu items for setting the Row and Column Span and there are also layout text fields for the same on the far right. Unfortunately, StackOverflow compresses the pic and makes it a little blurry.
Sample FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
<children>
<GridPane layoutX="116.0" layoutY="155.0">
<children>
<Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Button" GridPane.columnIndex="0" GridPane.columnSpan="2147483647" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS" />
<Label text="Label" GridPane.columnIndex="0" GridPane.rowIndex="0" />
<Label maxWidth="-1.0" text="Label" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0" />
<Label text="Label" GridPane.columnIndex="0" GridPane.rowIndex="2" />
<Label text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2" GridPane.rowSpan="2" />
<Label text="Label" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<Label text="Label" GridPane.columnIndex="2" GridPane.rowIndex="3" />
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="30.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="30.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="30.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="30.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</children>
</AnchorPane>

Resources