Minimal JavaFx project without fxml, controller and launcher

已回答

Just for learning and testing purpose. First I create normally a javafx project with java and gradle with no additional libraries.

After creation of JavaFx, IntellJ normally created three classes, HelloApplication, HelloController and Launcher, there are also hello-view.fxml. First I run the project, open up Launcher class and debug or run it with following configuration and a little issue, why is there warning?

I want just to have only one class MainApp, so renamed HelloApplication to MainApp, delete hello-view.fxml, HelloController and Launcher classes, modify also build script from HelloApplication to MainApp. But i have issue with running or debugging.

There are now just only one class MainApp here.

 

Contant of MainApp is

package com.company.javafxgradlewrapperdemo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MainApp extends Application {

    @Override
    public void start(Stage stage) {
        Label label = new Label("Hello JavaFX 👋 (Gradle Wrapper, minimal)");
        Button button = new Button("Click me");
        button.setOnAction(e -> label.setText("Clicked!"));

        VBox root = new VBox(10, label, button);
        Scene scene = new Scene(root, 320, 200);

        stage.setTitle("JavaFX Minimal with Wrapper");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

content of build.gradle.kts

plugins {
    java
    application
    id("org.javamodularity.moduleplugin") version "1.8.15"
    id("org.openjfx.javafxplugin") version "0.0.13"
    id("org.beryx.jlink") version "2.25.0"
}

group = "com.company"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

val junitVersion = "5.12.1"

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

tasks.withType<JavaCompile> {
    options.encoding = "UTF-8"
}

application {
    mainModule.set("com.company.javafxgradlewrapperdemo")
    mainClass.set("com.company.javafxgradlewrapperdemo.MainApp")
}

javafx {
    version = "21.0.6"
    modules = listOf("javafx.controls")
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}

tasks.withType<Test> {
    useJUnitPlatform()
}

jlink {
    imageZip.set(layout.buildDirectory.file("/distributions/app-${javafx.platform.classifier}.zip"))
    options.set(listOf("--strip-debug", "--compress", "2", "--no-header-files", "--no-man-pages"))
    launcher {
        name = "app"
    }
}
 

Only change the configuration from Launcher class to MainApp

After running I got this

How can I solve this problem, just only one class MainApp without Launcher, controller and fxml?

0

Hi Yong,

Your `MainApp.java` code is correct. The problem isn't in your code, but in how the application is being launched from within IntelliJ. The error "JavaFX runtime components are missing" appears because the standard “run” button (the green arrow) doesn't tell the JVM where to find the JavaFX modules.

The correct and easiest way to run your project is to use the built-in Gradle “run” task, which is already configured to do this for you.

Here’s how:

  1. In IntelliJ, open the Gradle tool window on the right side.
  2. Navigate to Tasks -> application.
  3. Double-click the “run” task (See the screenshot).

This should launch your application successfully.

Hope this helps!

0

Hello Aram,

thanks you for your help. I also get it work, with Gradle Tool run. Just for understanding. If I do not delete Launcher class, the standard “run” button (the green arrow), also work without click on "run" task in Gradle tool windows.

But why is it so, that without Launcher class, standard run button does not work any more?

0

Hi Yong,

You need the Launcher class to use the simple 'Run' button because it acts as a clever workaround to a strict check that JavaFX performs.

Here’s the process:

  1. The Problem: When your main class (like MainApp) extends javafx.application.Application, JavaFX requires special module information to start. The simple 'Run' arrow in the IDE does not provide this, so it fails.
  2. How the Launcher Solves It: The Launcher is a plain Java class that does not extend Application.
    • When you click 'Run' on the Launcher, JavaFX sees this plain class and skips its strict module check.
    • Once the Launcher is running, its only job is to start your real MainApp class. The check has already been bypassed, so your application loads successfully.

Think of the Launcher as a helper whose only purpose is to start your main application in a way that is compatible with the IDE's simple 'Run' button.

Hope that clarifies it!

0

请先登录再写评论。