Search code examples
javagradlejavafx

How do I display the app version on screen?


I want to display the current version of my app on screen (using a Label).

  • How I can do it?
  • Where do I need to set version variable if I use Gradle?
  • Or how can I get the version from the build.gradle file?
  • Or how can I get the version from an external file like manifest to use it in build.gradle?

Or, how do I display the current version of my app on screen, where I need to set this current version and how to use this version in Gradle?


Solution

  • One way I've done this in the past is to leverage the build tool to fill in placeholders in a properties file resource, then load that properties file at run-time. This is the same as described by jewelsea in the question comments.

    In Maven there are various ways to write the project version to a properties file, there should be a similar mechanism with Gradle.

    Once the version is in a properties file, you can load the properties from a resource stream (or inject the property values if you are using Spring) and set that as text in a JavaFX Label to display in your UI.

    The primary benefit of this approach is that it keeps your build tool as the source of truth. Change the value and it will automatically propagate to the built application.


    Example

    Here is an example tested with Java 22.0.2, JavaFX 22.0.2, and Gradle 8.9. This example uses the project's version as the application's version, but you can of course use a different value if the two versions are not the same.

    Resources

    app.properties

    app.version = ${version}
    

    Java Sources

    Main.java

    package sample;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    import java.util.Properties;
    
    public class Main extends Application {
    
      private String appVersion;
    
      @Override
      public void init() throws Exception {
        var props = new Properties();
        try (var in = Main.class.getResourceAsStream("/app.properties")) {
          props.load(in);
        }
        appVersion = props.getProperty("app.version", "<NO-VERSION>");
      }
    
      @Override
      public void start(Stage primaryStage) throws Exception {
        var label = new Label("Hello, from Example v" + appVersion + "!");
        primaryStage.setScene(new Scene(new StackPane(label), 500, 300));
        primaryStage.setTitle("Example - " + appVersion);
        primaryStage.show();
      }
    }
    

    Gradle Files (Kotlin DSL)

    settings.gradle.kts

    rootProject.name = "demo"
    

    build.gradle.kts

    plugins {
      id("org.openjfx.javafxplugin") version "0.1.0"
      application
    }
    
    group = "sample"
    version = "0.1.0"
    
    repositories { 
      mavenCentral()
    }
    
    javafx {
      modules("javafx.controls")
      version = "22.0.2"
    }
    
    application {
      mainClass = "sample.Main"
    }
    
    tasks {
      // This is the part responsible for filling in the placeholders in the
      // properties file.
      processResources {
        inputs.property("version", project.version) // Configure task to rerun if value changes
        filesMatching("app.properties") {
          expand("version" to project.version)
        }
      }
    }
    

    Project Directory

    <project-dir>
    |   build.gradle.kts
    |   gradlew
    |   gradlew.bat
    |   settings.gradle.kts
    |   
    +---gradle
    |   |   
    |   \---wrapper
    |           gradle-wrapper.jar
    |           gradle-wrapper.properties
    |           
    \---src
        \---main
            +---java
            |   \---sample
            |           Main.java
            |           
            \---resources
                    app.properties
    

    Output

    Here is the result from running ./gradlew run.

    Screenshot of UI.