JavaFX ProGuard app is not working after obfuscate - maven

i'm writing this question after 4 days of trying obfuscate my javaFX app without success...
About project:
JDK: Azul JavaFX 8.42.0.23
Build tool: Maven
Ide: Intelij
ProGuard ver: 6.2.2
What is the problem:
I cant properly obfuscate my code. After build app as native and also as fatjar everything working fine. After obfuscate i have below error:
javafx.fxml.LoadException:
file:/C:/Users/pawel/Desktop/X/X/target/X-1.3-jar-with-dependenciesOBF.jar!/fxml/MainWindow.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2848)
at javafx.fxml.FXMLLoader.processImport(FXMLLoader.java:2692)
at javafx.fxml.FXMLLoader.processProcessingInstruction(FXMLLoader.java:2661)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2517)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at c.b.g(SourceFile:227)
at c.b.i(SourceFile:36)
at c.b$5.a(SourceFile:194)
at c.b$5.a(SourceFile:183)
at com.d.a.a$1.a(SourceFile:32)
at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException
at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2899)
at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2846)
... 17 more
Current progard settings:
-injars 'C:\Users\pawel\Desktop\PROJEKTY JAVA\x\target\jfx\native\x\app\x-1.3-jfx.jar'
-outjars 'C:\Users\pawel\Desktop\PROJEKTY JAVA\x\target\jfx\native\x\app\x-1.3-jfxOBF.jar'
-injars 'C:\Users\pawel\Desktop\PROJEKTY JAVA\x\target\x-1.3-jar-with-dependencies.jar'
-outjars 'C:\Users\pawel\Desktop\PROJEKTY JAVA\x\target\x-1.3-jar-with-dependenciesOBF.jar'
-libraryjars 'C:\Program Files\Java\jre1.8.0_181\lib\rt.jar'
-libraryjars 'C:\Program Files\Java\jre1.8.0_181\lib\javaws.jar'
-libraryjars 'C:\Program Files\Java\jre1.8.0_181\lib\ext\jfxrt.jar'
-verbose
-dontnote
-dontwarn
-dontoptimize
-dontshrink
# Keep names of fields marked with #FXML, #Inject and #PostConstruct attributes
-keepclassmembers class * {
#javafx.fxml.FXML *;
#javax.inject.Inject *;
#javax.annotation.PostConstruct *;
}
# Keep entry-point class
-keep class main.Main {
public static void main(java.lang.String[]);
}
# Keep all annotations and meta-data
-keepattributes *Annotation*,Signature,EnclosingMethod
# Save meta-data for stack traces
-printmapping out.map
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
# Rename FXML files together with related views
-adaptresourcefilenames **.fxml,**.png,**.css,**.properties
-adaptresourcefilecontents **.fxml
-adaptclassstrings
Additionally i checked advices from stackoverflow:
Update all names of FXML files to staring with uppercase
Add list of all classnames as classobfuscationdictionary
Additional information, i have preloader of application (single fxml with logo and loadning bar) and it's working. Problem is when im trying load main window of app where fxml contain include tags.
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXProgressBar?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<BorderPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="2000.0" prefWidth="2000.0" style="-fx-background-color: #323234;" styleClass="main-container" stylesheets="#../css/mainStyles.css" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainScreenController">
<children>
<VBox layoutX="300.0" layoutY="31.0" prefHeight="358.0" prefWidth="289.0">
<children>
<HBox alignment="CENTER" spacing="20.0" VBox.vgrow="ALWAYS">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<VBox.margin>
<Insets />
</VBox.margin>
</HBox>
<HBox prefHeight="100.0" prefWidth="200.0" />
<HBox prefHeight="100.0" prefWidth="200.0" />
</children>
</VBox>
</children>
<left>
<fx:include source="menus/MenuLeft.fxml" BorderPane.alignment="TOP_LEFT" />
</left>
<top>
<fx:include source="menus/MenuTop.fxml" />
</top>
<bottom>
<JFXProgressBar fx:id="progressBar" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="3.0" BorderPane.alignment="CENTER" />
</bottom>
<center>
<ScrollPane fitToHeight="true" fitToWidth="true" BorderPane.alignment="TOP_LEFT">
<content>
<VBox fx:id="vContainer" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" />
</content>
</ScrollPane>
</center>
</BorderPane>

After 5 days of looking i have solution.
Problem is causing by imports in fxml file from outside of the javax package. To fix this we have to:
Check below checkbox:
And add imports as "keep"
with methods and fields and two stars**:

Related

How to load an fxml file from a controller that is linked to a different fxml file?

I am building a JavaFX which has two windows: a signin window and a register window. The fxml file of the former has a "username" label and text field, a "password" label and text field, a "signin" button, a "close" button and a hyperlink that reads "or create a new user". I want that when users click on the hyperlink, a registration window pop-up with labels and text fields asking for the user to enter a user name, password, first name, etc.
I have a Login.fxml file and a LoginController.java file for the sign in window. And for the registration window I have a CreateUser.fxml file and a CreateUSerController.java file.
My problem is how to load the CreateUser.fxml file (and make the registration window pop-up) from the LoginController.java file. I handle the clicking on the "or create a new user" hyperlink event in LoginController.java, and basically the result I expect of the handling is to make the registration window to pop-up. I get a runtime error.
When I click on the "or create a new user" hyperlink in the login window I get the following error: The Eclipse debugger says "Thread[JavaFX Application Thread](Suspended(uncaught exception RuntimeException))". Also, when I check the value of the variables during execution there is a "runWithoutRenderLock() is throwing", and its value is RuntimeException. Also says that its cause is a "InvocationTargetException", and that the cause of this exception is a "null". Also, a "QuantumToolkit.class" tab appears in eclipse with the message "Source not found" "The JAR file ... has no source attachment". It also has a clickable button that reads "Attach source"
To load "CreateUser.fxml" from "LoginController.java" I used a handler which tries to load the fxml file with this line of code: "root = FXMLLoader.<Parent>load(CreateUserController.class.getResource("CreateUser.fxml"));". Here is where the exception occurs
Please find below my Main class which is where I load the "Login.fxml" file, the "Login.fxml", "LoginController.java", "CreateUser.fxml" and CreateUSerController.java files. Also, an image of my file structure.
File structure
src
/application
-Main.java
/controller
-LoginController.java
-CreateUserController.java
/model
/view
-Login.fxml
-CreateUser.fxml
-module-info.java
Main.java
package application;
import java.io.IOException;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
#Override
public void start(Stage signinStage) throws IOException {
try {
BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("/view/Login.fxml"));
Scene scene = new Scene(root,400,400);
signinStage.setTitle("Welcome to MyHEalth");
signinStage.setScene(scene);
signinStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
launch(args);
}
}
Login.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<BorderPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.LoginController">
<center>
<VBox alignment="CENTER" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="400.0" BorderPane.alignment="CENTER">
<children>
<Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="21.0" prefWidth="300.0" text="Username">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</Label>
<TextField fx:id="userNameField" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="300.0">
<VBox.margin>
<Insets bottom="20.0" />
</VBox.margin>
</TextField>
<Label prefHeight="17.0" prefWidth="300.0" text="Password">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</Label>
<TextField fx:id="passwordField" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="300.0" />
<BorderPane prefHeight="100.0" prefWidth="200.0">
<center>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="170.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="signinButton" maxWidth="-Infinity" mnemonicParsing="false" onAction="#signin" prefWidth="70.0" text="Sign in" />
<Button fx:id="closeButton" alignment="CENTER" maxWidth="-Infinity" mnemonicParsing="false" onAction="#close" prefWidth="60.0" text="Close" textAlignment="RIGHT">
<HBox.margin>
<Insets left="40.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</center>
<bottom>
<Hyperlink fx:id="newUserLink" onAction="#openNewUserWindow" text="or create new user" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
</children>
</VBox>
</center>
</BorderPane>
LoginController.java
package controller;
import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import model.User;
public class LoginController {
#FXML
private Button closeButton;
#FXML
private Hyperlink newUserLink;
#FXML
private TextField passwordField;
#FXML
private Button signinButton;
#FXML
private TextField userNameField;
private Stage stage;
private Parent root;
#FXML
void signin(ActionEvent event) {
passwordField.getText();
userNameField.getText();
User user = new User(passwordField.getText(), "first name", "last name", userNameField.getText(), "imagepath");
//still have to get the rest of the information from the database
System.out.print(user.getProfile().getFirstName());//debugging message
}
#FXML
void close(ActionEvent event) {
System.out.print("Thanks for visiting MyHealth. Bye");
System.exit(0);
}
#FXML
void openNewUserWindow(ActionEvent event) {
try {
System.out.print("1st line Inside 'try' block of 'openNewUserWindow' in LoginController");
//System.out.println("\nJust after FXMLLoader Inside 'try' block of 'openNewUserWindow' in LoginController");
root = FXMLLoader.<Parent>load(CreateUserController.class.getResource("CreateUser.fxml"));
//System.out.print("last line Inside 'try' block of 'openNewUserWindow' in LoginController");
}
catch(IOException e){
System.out.print("Problem getting 'CreateUSer.fxml'");
}
Stage createUserStage = new Stage();
Scene createUserScene = new Scene(root, 400, 400);
createUserStage.setScene(createUserScene);
createUserStage.setTitle("Create a new user");
createUserStage.show();
}
}
CreateUser.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.CreateUserController">
<children>
<VBox layoutY="30.0" prefHeight="440.0" prefWidth="400.0">
<children>
<ImageView fitHeight="82.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true">
<VBox.margin>
<Insets left="150.0" top="10.0" />
</VBox.margin>
</ImageView>
<Label fx:id="clickImage" text="Click to select profile picture" textFill="#00000093">
<VBox.margin>
<Insets bottom="20.0" left="125.0" />
</VBox.margin>
</Label>
<Label text="Username">
<VBox.margin>
<Insets bottom="5.0" left="50.0" />
</VBox.margin>
</Label>
<TextField fx:id="userName" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="280.0">
<VBox.margin>
<Insets bottom="10.0" left="50.0" />
</VBox.margin>
</TextField>
<Label text="First name">
<VBox.margin>
<Insets bottom="5.0" left="50.0" />
</VBox.margin>
</Label>
<TextField fx:id="firstName" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="280.0">
<VBox.margin>
<Insets bottom="10.0" left="50.0" />
</VBox.margin>
</TextField>
<Label text="Last name">
<VBox.margin>
<Insets bottom="5.0" left="50.0" />
</VBox.margin>
</Label>
<TextField fx:id="lastName" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="280.0">
<VBox.margin>
<Insets bottom="10.0" left="50.0" />
</VBox.margin>
</TextField>
<Label text="Password">
<VBox.margin>
<Insets bottom="5.0" left="50.0" />
</VBox.margin>
</Label>
<TextField fx:id="password" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="280.0">
<VBox.margin>
<Insets bottom="10.0" left="50.0" />
</VBox.margin>
</TextField>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<Button fx:id="createButton" mnemonicParsing="false" onAction="#create" text="Create user">
<HBox.margin>
<Insets left="100.0" top="15.0" />
</HBox.margin>
</Button>
<Button fx:id="closeButton" mnemonicParsing="false" onAction="#close" text="Close">
<HBox.margin>
<Insets left="30.0" top="15.0" />
</HBox.margin>
</Button>
</children>
</HBox>
<Label fx:id="createdLabel" text="Created user" textFill="#2b784f">
<VBox.margin>
<Insets left="125.0" top="20.0" />
</VBox.margin>
</Label>
</children>
</VBox>
</children>
</VBox>
</children>
</AnchorPane>
CreateUSerController.java
package controller;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class CreateUserController {
#FXML
private Label clickImage;
#FXML
private Button closeButton;
#FXML
private Button createButton;
#FXML
private Label createdLabel;
#FXML
private TextField firstName;
#FXML
private TextField lastName;
#FXML
private TextField password;
#FXML
private TextField userName;
#FXML
void close(ActionEvent event) {
}
#FXML
void create(ActionEvent event) {
}
}
First of all, I personally prefer to instantiate a new FXMLLoader instance to load a fxml file. Then you can also specify a location and some other kind of stuff like a controller factory.
You can lookup the setter methods here: https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.html
But in this case your only mistake is that you load the fxml from the wrong class location.
When you use "CreateUserController.class.getResource("CreateUser.fxml")", it will try to find the fxml file in the same directory like the class. You have to use another path like you did before with the login fxml file. ("/view/CreateUser.fxml")
I hope that helps.

JavaFx Project Error : Caused by: com.sun.javafx.fxml.PropertyNotFoundException: Property "iconName" does not exist or is read-only

so I'm trying to run this project and it displays this error eventhough I added the fontawesomefx-8.2.jar
Caused by: java.lang.RuntimeException: Exception in Application start
method at
com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$159(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: javafx.fxml.LoadException: file:/C:/Users/Yasmine%20Daly/Downloads/Gaming%20Dashboard/Gaming%20Dashboard/dist/run1549224879/Gaming%20Dashboard.jar!/gaming/dashboard/UI.fxml:23
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097) at gaming.dashboard.GamingDashboard.start(GamingDashboard.java:13) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$166(LauncherImpl.java:863) at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$179(PlatformImpl.java:326) at com.sun.javafx.application.PlatformImpl.lambda$null$177(PlatformImpl.java:295) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl.lambda$runLater$178(PlatformImpl.java:294) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$152(WinApplication.java:177) ... 1 more Caused by: com.sun.javafx.fxml.PropertyNotFoundException: Property "iconName" does not exist or is read-only. at javafx.fxml.FXMLLoader$Element.processValue(FXMLLoader.java:348) at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:325) at javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:235) at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:767) at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2823) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2532) ... 17 more Exception running application gaming.dashboard.GamingDashboard Java Result: 1
This is the UI file where the iconName exists and is underlined in red;
<FontAwesomeIcon iconName="MUSIC" layoutX="32.0" layoutY="134.0" size="1.5em" styleClass="sidebar-icon" />
<FontAwesomeIcon iconName="GEAR" layoutX="32.0" layoutY="175.0" size="1.5em" styleClass="sidebar-icon" />
<FontAwesomeIcon iconName="FILE" layoutX="34.0" layoutY="210.0" size="1.2em" styleClass="sidebar-icon" />
<FontAwesomeIcon iconName="DASHBOARD" layoutX="33.0" layoutY="242.0" size="1.2em" styleClass="sidebar-icon" />
<FontAwesomeIcon iconName="MUSIC" layoutX="32.0" layoutY="278.0" size="1.2em" styleClass="sidebar-icon" />
<FontAwesomeIcon iconName="HEART" layoutX="32.0" layoutY="368.0" size="1.2em" styleClass="sidebar-icon" />
<FontAwesomeIcon iconName="GEAR" layoutX="31.0" layoutY="399.0" size="1.5em" styleClass="sidebar-icon" />
If the following is addressed, then I can use font awesome icons from FXML:
As it says, iconName is not a property of FontAwesomeIcon.
FontAwesomeIcon is an enum and not a node, so I don't know how you would use it from FXML.
There is a FontAwesomeIconView which is a node and has a property called glyphName and can be used instead.
Ensure recent versions, Java/JavaFX 17.0.2 and fontawesomefx 4.7.0-9.1.2.
Following the instructions here:
Load custom components in scenebuilder 17
Using the following fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.HBox?>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1">
<children>
<FontAwesomeIconView glyphName="MUSIC" size="1.5em" />
<FontAwesomeIconView glyphName="GEAR" size="1.5em" />
<FontAwesomeIconView glyphName="FILE" size="1.5em" />
<FontAwesomeIconView glyphName="DASHBOARD" size="1.5em" />
<FontAwesomeIconView glyphName="HEART" size="1.5em" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</HBox>
Displays the following output in SceneBuilder:
To have this work in an app, you need to use a recent JDK and JavaFX, e.g. 17.0.2, as well as a recent FontAwesomeFX version and load the FXML into your app.
<dependency>
<groupId>de.jensd</groupId>
<artifactId>fontawesomefx-fontawesome</artifactId>
<version>4.7.0-9.1.2</version>
</dependency>
See this question for an example of access via an app:
Unable to import certain classes in fontawesomefx after updating for Java 9 / Java 11
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class FontApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(FontApplication.class.getResource("fonts.fxml"));
stage.setScene(new Scene(fxmlLoader.load()));
stage.show();
}
public static void main(String[] args) {
launch();
}
}

Populating ComboBox with JAVA FX MVC

I need to populate JAVAFX ComboBox with value using an MVC but somehow i cant get the combobox to work. Please help me,,
LoginController.java
package weltes.finance.controller;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
/**
* Created by engineering09 on 12/18/2015.
*/
public class LoginController {
#FXML private ComboBox userComboBox;
#FXML private void fillComboBox(){
userComboBox.getItems().addAll("Item1", "Item2");
}
}
loginscreen.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="163.0" prefWidth="357.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="weltes.finance.controller.LoginController">
<children>
<ComboBox fx:id="userComboBox" layoutX="15.0" layoutY="14.0" prefHeight="25.0" prefWidth="328.0" promptText="Select Registered User" />
<PasswordField layoutX="15.0" layoutY="56.0" prefHeight="25.0" prefWidth="328.0" promptText="Enter Password" />
<Button layoutX="15.0" layoutY="97.0" mnemonicParsing="false" prefHeight="51.0" prefWidth="328.0" text="Button" />
</children>
</AnchorPane>
First list the items in the FXML.
<ComboBox fx:id="userComboBox" editable="false" layoutX="14.0" layoutY="22.0" onAction="#setTimeMultiplier">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Item 1" />
<String fx:value="Item 2" />
<String fx:value="Item 3" />
</FXCollections>
</items>
</ComboBox>
Then add or remove items from the ObservableArrayList.
userComboBox.getItems().removeAll(comboTime.getItems());
userComboBox.getItems().addAll(...);

How to make a resizable SplitPane within a Tab in JavaFX 2.0 (preferably using SceneBuilder and/or FXML)?

The question basically says it all, with the caveat that I'm a newbie to GUI design in general and JavaFX in particular. To reproduce in SceneBuilder, drag a TabPane onto the scene, and drag a SplitPane into the first tab's AnchorPane. Adjust (drag) the size of the SplitPane to match the the size of the tab. This is not a problem if the SplitPane is not a child (I only tested it as a (grand)child of a Tab so far). You'll have something like this:
Upon preview, if you try to expand the window size by dragging, the SplitPane won't resize:
Here is the FXML I get from SceneBuilder, using the process described at the top of this post with perhaps a few minor changes that didn't help:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="0.0" minWidth="0.0" prefHeight="386.0" prefWidth="613.0">
<children>
<SplitPane dividerPositions="0.29797979797979796" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="358.0" prefWidth="600.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="158.0" prefWidth="277.0" />
</items>
</SplitPane>
</children></AnchorPane>
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
The problem is that your SplitPane is a child of an AnchorPane. In case you have something under AnchorPane, it is anchored to specific co-ordinates. To allow the child to take up the whole are, you need to specify the AnchorPane's anchor to zero.
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<tabs>
....
<SplitPane dividerPositions="0.29797979797979796" maxHeight="-Infinity"
maxWidth="-Infinity" prefHeight="358.0" prefWidth="600.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
....
</tabs>
</TabPane>
Using scene-builder, you can assign the AnchorPane Constraints by:
Select the child under AnchorPane
Move to Layout section on the right hand side panel
You will see a section called AnchorPane constraints, just type in the four section values and save

LoadException with FXML created with Scene Builder

I've generated FXML in Scene Builder:
<?xml version="1.0" encoding="UTF-8"?>
<?scenebuilder-preview-i18n-resource ../lang/ru_RU.properties?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" fx:id="mainStagePane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="UI.MainStageController">
<children>
<SplitPane dividerPositions="0.6596244131455399" focusTraversable="true" prefHeight="-1.0" prefWidth="1280.0" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="160.0">
<items>
<AnchorPane id="rootPane" fx:id="pane3d" prefHeight="930.0" prefWidth="1280.0" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<Accordion id="accordeon" fx:id="accordion" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<panes>
<TitledPane animated="true" text="%3dSceneSettings" fx:id="x2">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Slider fx:id="farClipSlider" layoutY="50.0" majorTickUnit="10.0" max="100.0" min="-100.0" minorTickCount="1" prefWidth="337.0" showTickLabels="true" showTickMarks="true" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="75.0" />
<TextField layoutY="14.0" prefWidth="55.0" AnchorPane.rightAnchor="217.0" />
<Slider fx:id="distanceSlider" blockIncrement="25.0" layoutX="14.0" layoutY="133.0" majorTickUnit="50.0" max="500.0" min="-500.0" minorTickCount="25" prefWidth="399.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" />
<VBox layoutY="364.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0">
<children>
<HBox prefHeight="-1.0" prefWidth="-1.0">
<children>
<Label text="Label" />
<TextField prefWidth="55.0" />
</children>
</HBox>
<Slider fx:id="nearClipSlider" blockIncrement="1.0" majorTickUnit="10.0" max="100.0" min="-100.0" minorTickCount="1" prefWidth="338.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="0.0" />
</children>
</VBox>
<Label layoutX="104.0" layoutY="17.0" text="Label" />
</children>
</AnchorPane>
</content>
</TitledPane>
<TitledPane animated="true" expanded="false" text="%3dModelSettings" fx:id="x1">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</TitledPane>
</panes>
</Accordion>
</children>
</AnchorPane>
</items>
</SplitPane>
<ToolBar maxHeight="30.0" minHeight="30.0" prefHeight="30.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<items>
<ProgressBar fx:id="loadProgressBar" disable="false" prefWidth="200.0" progress="0.0" visible="true" />
</items>
</ToolBar>
<TabPane prefHeight="160.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<tabs>
<Tab text="%file">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Button alignment="CENTER" graphicTextGap="4.0" mnemonicParsing="false" prefHeight="90.0" prefWidth="90.0" text="%openFile" textAlignment="CENTER" textOverrun="ELLIPSIS" underline="false" wrapText="true" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
<Separator layoutX="170.0" orientation="VERTICAL" prefHeight="200.0" AnchorPane.bottomAnchor="10.0" AnchorPane.topAnchor="10.0" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab text="%analysis">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Button mnemonicParsing="false" prefHeight="90.0" prefWidth="90.0" text="Button" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
But suddenly I received the following exception:
javafx.fxml.LoadException:
/D:/Projects/CastAnalytics/out/production/CastAnalytics/UI/MainStage.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2592)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2570)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2416)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3160)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3121)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3094)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3070)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3062)
at core.CastAnalytics.start(CastAnalytics.java:32)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:331)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:297)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NullPointerException
at UI.MainStageController.set(MainStageController.java:98)
at UI.MainStageController.initialize(MainStageController.java:34)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2523)
... 18 more
What does it mean and how can I fix it?
Well, you've got a null pointer at line 98 of MainStageController....
If I had to guess, I'd say that one of the #FXML variables you've defined in your Controller isn't named the same as in your FXML file, so you're getting a NPE.
You'd have to paste the relevant MainStageController.java code for anyone to know more.
Please post the offending line or SSCE if possible. I agree with jhsheets and your approach double checking the variable names against your fx:id names. I have encountered this exact error/situation myself at exactly the same place (in the initialize method trying to do some post-loading initialization) where a small typo in my fx:I'd caused an NPE. But it would be good to know what is going on in the set method where the NPE originates.

Resources