Reputation: 11
I recently completed a school management program with JavaFX 18 which runs properly using the normal IntelliJ run configurations but fails to load ALL icons from org.kordamp.materialdesign2. I have scanned the entire web and come across a few answers regarding service files. I have all three required packages in my module-info file org.kormap.ikoli.core,org.kordamp.javafx and org.kordamp.materialdesign2
When the jar is run, it shows messages like this:
Exception in thread "JavaFX Application Thread" java.lang.UnsupportedOperationException: Cannot resolve 'mdi2o-office-building'
at org.kordamp.ikonli.AbstractIkonResolver.resolve(AbstractIkonResolver.java:61)
at org.kordamp.ikonli.javafx.IkonResolver.resolve(IkonResolver.java:73)
at org.kordamp.ikonli.javafx.FontIcon.lambda$new$2(FontIcon.java:76)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:106)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:113)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.css.StyleableObjectProperty.set(StyleableObjectProperty.java:82)
at org.kordamp.ikonli.javafx.FontIcon.setIconCode(FontIcon.java:231)
at org.kordamp.ikonli.javafx.FontIcon.<init>(FontIcon.java:97)
at manager.school_manager.EntryController.initialize(EntryController.java:115)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at manager.school_manager.Entry.start(Entry.java:56)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:1589)
error messages on running jar | Program without icons on running jar | Program showing icons when run in intellij
module-info.java with all three co-dependencies
build.gradle file showing use of shadow jar plugin
Also opened the jar file with winrar and checked the Manifest/Manifest.MF/services and here is what I found:
Upvotes: 0
Views: 270
Reputation: 1
I have faced the same issue here and I just think of creating my own Icon library at this point
Upvotes: 0
Reputation: 11
module-info.java
module manager.school_manager {
//javafx and related deps
requires javafx.controls;
requires javafx.fxml;
requires org.controlsfx.controls;
requires com.dlsc.formsfx;
requires org.jfxtras.styles.jmetro;
requires org.kordamp.ikonli.javafx;
requires org.kordamp.ikonli.materialdesign2;
requires org.kordamp.ikonli.core;
requires javafx.base;
requires java.desktop;
requires javafx.graphics;
requires javafx.web;
requires javafx.media;
// json io
requires com.google.code.gson;
//itext 7 ===> pdf deps
requires itextpdf.layout;
requires itextpdf.kernel;
requires itextpdf.io;
requires itextpdf.commons;
requires itextpdf.pdfa;
requires itextpdf.barcodes;
// postgres deps
requires java.sql;
requires org.postgresql;
//excel deps
requires org.apache.poi.ooxml;
//logging deps and transitive deps
requires org.slf4j;
requires commons.math3;
opens manager.school_manager to javafx.fxml;
opens manager.school_manager.controllers to javafx.fxml;
exports manager.school_manager;
}`
build.gradle
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.10'
id 'org.beryx.jlink' version '2.24.1'
id 'org.gradlex.extra-java-module-info' version '1.3'
id 'java-library'
// id 'com.github.johnrengelman.shadow' version '6.1.0'
}
//shadowJar {
// mergeServiceFiles()
//}
//
group 'manager'
version '1.0-SNAPSHOT'
ext.moduleName= 'manager.school_manager'
extraJavaModuleInfo{
failOnMissingModuleInfo.set(false)
module("org.tinylog:tinylog-api","org.tinylog.api"){
exportAllPackages()
requireAllDefinedDependencies
}
module("org.tinylog:tinylog-impl","org.tinylog.impl"){
exportAllPackages()
requireAllDefinedDependencies
}
module("com.google.code.gson:gson","com.google.code.gson"){
exportAllPackages()
requireAllDefinedDependencies
}
module("io.github.typhon0:AnimateFX","io.github.typhon0"){
exportAllPackages()
requireAllDefinedDependencies
}
module("com.github.Dansoftowner:PDFViewerFX","com.github.Dansoftowner"){
exportAllPackages()
requireAllDefinedDependencies
}
module("org.apache.commons:commons-math3","commons.math3"){
exportAllPackages()
requireAllDefinedDependencies
}
module("com.zaxxer:SparseBitSet","SparseBitSet"){
exportAllPackages()
requireAllDefinedDependencies
}
automaticModule("fxribbon.jar","com.pixelduke.fxribbon")
automaticModule("postgresql.jar","org.postgresql")
automaticModule("log4j.jar","org.log4j")
automaticModule("log4j-api.jar","org.log4j-api")
automaticModule("slf4j-api.jar","org.slf4j")
automaticModule("layout.jar","itextpdf.layout")
automaticModule("kernel.jar","itextpdf.kernel")
automaticModule("pdfa.jar","itextpdf.pdfa")
automaticModule("io.jar","itextpdf.io")
automaticModule("commons.jar","itextpdf.commons")
automaticModule("barcodes.jar","itextpdf.barcodes")
automaticModule("sign.jar","itextpdf.sign")
automaticModule("svg.jar","itextpdf.svg")
automaticModule("javafxweb.jar","javafx.web")
automaticModule("javafxmedia.jar","javafx.media")
}
repositories {
mavenCentral()
maven{
url "https://plugins.gradle.org/m2/"
}
maven {
url "https://jitpack.io"
}
}
ext {
junitVersion = '5.9.2'
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
application {
mainModule = 'manager.school_manager'
mainClass = 'manager.school_manager.Main'
}
javafx {
version = '11.0.2'
modules = ['javafx.controls', 'javafx.fxml']
}
dependencies {
// converts non modular jars to jpms compatible
implementation('org.gradlex:extra-java-module-info:1.3')
//
// implementation('com.google.firebase:firebase-admin:9.1.1')
implementation('org.controlsfx:controlsfx:11.1.2')
implementation('com.dlsc.formsfx:formsfx-core:11.6.0') {
exclude(group: 'org.openjfx')
}
implementation('net.synedra:validatorfx:0.4.0') {
exclude(group: 'org.openjfx')
}
implementation('org.jfxtras:jmetro:11.6.16')
implementation(fileTree(dir:'/libs',includes:['*.jar']))
// implementation('org.openpnp:opencv:3.4.2-0')
// implementation('eu.hansolo.fx:charts:17.1.27')
implementation('org.tinylog:tinylog-api:2.6.1')
implementation('org.tinylog:tinylog-impl:2.6.1')
implementation('com.google.code.gson:gson:2.3.1')
implementation('io.github.typhon0:AnimateFX:1.2.4')
implementation('org.kordamp.ikonli:ikonli-materialdesign2-pack:12.3.1')
implementation 'org.kordamp.ikonli:ikonli-core:12.3.1'
implementation('org.kordamp.ikonli:ikonli-javafx:12.3.1')
implementation('org.apache.poi:poi-ooxml:5.2.3'){
exclude(group: "javax.xml")
}
implementation('com.zaxxer:SparseBitSet:1.2')
implementation 'org.kordamp.jipsy:jipsy-annotations:1.2.0'
// implementation 'org.apache.xmlgraphics:batik-transcoder:1.13'
testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}
test {
useJUnitPlatform()
}
jlink {
imageZip = project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip") as RegularFile
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
launcher {
name = 'app'
}
}
jlinkZip {
group = 'distribution'
}
Main.java *** a simple entry that show the icon implementation throughout the code in a simple Label ***
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.materialdesign2.*;
... other imports
public class Main extends Application {
@Override
public void start(Stage stage) throws IOException, ClassNotFoundException, SQLException {
System.out.println("LAUCHING SMPRO....");
// loading main.fxml
FXMLLoader loader = new FXMLLoader();
URL fxmlLocation = ResourceAnchor.getAppResource("views/main.fxml");
loader.setLocation(fxmlLocation);
loader.setResources(ResourceBundle.getBundle(StaticNames.RESOURCE_BUNDLE_BASENAME.getName()));
Parent root = loader.<VBox>load();
root.getStyleClass().add(JMetroStyleClass.BACKGROUND);
// get controller instance
EntryController entryController = loader.getController();
entryController.EntryStage.set(stage);
Scene scene = new Scene(new Button("Click me",new FontIcon(MaterialDesignA.ACCOUNT_CIRCLE)));
stage.setTitle("Sample title");
stage.setScene(scene);
stage.setResizable(false);
stage.getIcons().add(new Image(ResourceAnchor.getResourceStream("images/logo.png")));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 0
Reputation: 159576
Example app
Build requires Maven installation and JDK 20 installation. Deployment is standalone and has no dependencies other than the OS it runs on.
src/main/java/module-info.java
module com.example.materialicons {
requires javafx.controls;
requires org.kordamp.ikonli.javafx;
requires org.kordamp.ikonli.materialdesign2;
exports com.example.materialicons;
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>materialicons</artifactId>
<version>1.0-SNAPSHOT</version>
<name>materialicons</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>20.0.2</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>12.3.1</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-materialdesign2-pack</artifactId>
<version>12.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>20</source>
<target>20</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<mainClass>com.example.materialicons/com.example.materialicons.IconApplication</mainClass>
<launcher>iconapp</launcher>
<jlinkZipName>iconapp</jlinkZipName>
<jlinkImageName>iconapp</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/java/com/example/materialicons/IconApplication.java
Material Design has icon packs, named A -> Z. We just use the A icon pack here, usage of icons from other packs is similar.
package com.example.materialicons;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.materialdesign2.MaterialDesignA;
public class IconApplication extends Application {
@Override
public void start(Stage stage) {
FlowPane layout = new FlowPane();
layout.setPadding(new Insets(10));
layout.setPrefWrapLength(500);
for (MaterialDesignA iconEnumVal : MaterialDesignA.values()) {
FontIcon icon = new FontIcon(
iconEnumVal.getDescription()
);
icon.setIconSize(40);
layout.getChildren().add(
icon
);
}
Scene scene = new Scene(new ScrollPane(layout), 530, 400);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Build
Build command (execute from the project root directory):
mvn clean javafx:jlink
Build output:
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< com.example:materialicons >----------------------
[INFO] Building materialicons 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ materialicons ---
[INFO] Deleting /Users/username/dev/materialicons/target
[INFO]
[INFO] >>> javafx-maven-plugin:0.0.8:jlink (default-cli) > process-classes @ materialicons >>>
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ materialicons ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/username/dev/materialicons/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.11.0:compile (default-compile) @ materialicons ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 2 source files with javac [debug target 20 module-path] to target/classes
[INFO]
[INFO] <<< javafx-maven-plugin:0.0.8:jlink (default-cli) < process-classes @ materialicons <<<
[INFO]
[INFO]
[INFO] --- javafx-maven-plugin:0.0.8:jlink (default-cli) @ materialicons ---
[INFO] Building zip: /Users/username/dev/materialicons/target/iconapp.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
Example usage
Execute from your project root directory. Adjust the command syntax for your OS type.
mkdir tmp
cd tmp
unzip ../target/iconapp.zip
bin/iconapp
Example output
Upvotes: 1