Search code examples
javajavafxgluongluon-desktop

System.setProperty("prism.allowhidpi", "false") does not work?


I'm trying to disable Windows display scaling (and in other OS) in my JavaFX application. Setting -Dprism.allowhidpi="false" in IntelliJ run configuration VM options works but setting the system property in code does not. I would like to set it in code so it works in any JVM setup like GraalVM / Gluon Substrate.

Is this a bug in JavaFX or how is it used in code? The following example does not work, the stage is scaled if scaling is set in Windows:

public class Main extends Application {

    public static void main(String[] args) {
        System.setProperty("prism.allowhidpi", "false");
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        stage.setWidth(1280);
        stage.setHeight(720);
        Scene scene = new Scene(new Label("SCALE TEST"));
        stage.setScene(scene);
        stage.show();
    }
}

EDIT: As noted in the comments, creating a seperate launcher class which sets the property and then calls the Application class works. However, it does not seem to work with Gluon Substrate. Here are relevant parts of my project. I also added two other prism properties to make sure the new main class is loaded properly in Substrate and the two other properties do indeed work. If I run mvn javafx:run the scaling is turned off, if I run mvn client:build and mvn client:run the scaling is on but everything else is the same.

public class Main {
    public static void main(String[] args) {
        System.setProperty("prism.allowhidpi", "false"); // doesn't work with Substrate
        System.setProperty("prism.lcdtext", "false"); // works
        System.setProperty("prism.subpixeltext", "false"); // works
        MainFXML.run(args);
    }
}

App

public class MainFXML extends Application {
    
    @Override
    public void start(Stage stage) throws Exception {
        String fxmlFile = "/fxml/FXMLDocument.fxml";
        FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlFile));
        Parent root = loader.load();
        root.getStylesheets().add(getClass().getResource("/styles/Style.css").toString());
        FXMLDocumentController gui = (FXMLDocumentController) loader.getController();

        Scene scene = new Scene(root);
        stage.setScene(scene); 
        stage.show();
        stage.setResizable(false);

        // create logic class etc
    }

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

Pom

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>ank</groupId>
    <artifactId>PROJ</artifactId>
    <name>PROJ</name>

    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <finalName>PROJ</finalName>
        <plugins>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.3</version>
                <configuration>
                    <mainClass>ank.fxml.Main</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.gluonhq</groupId>
                <artifactId>client-maven-plugin</artifactId>
                <version>0.1.38</version>
                <configuration>
                    <mainClass>ank.fxml.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>15</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.9.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>
    </dependencies>

</project>

I also tried setting properties in the pom-file as nativeImageArgs, but none of them worked.

    <plugin>
        <groupId>com.gluonhq</groupId>
        <artifactId>client-maven-plugin</artifactId>
        <version>0.1.38</version>
        <configuration>
            <mainClass>ank.fxml.Main</mainClass>
            <nativeImageArgs>
                <arg>-Dprism.allowhidpi=false</arg>
                <arg>-Dprism.lcdtext=false</arg>
                <arg>-Dprism.subpixeltext=false</arg>
            </nativeImageArgs>
        </configuration>
    </plugin>

Solution

  • After much searching I managed to get this to work, at least on Windows. Instead of using the prism.allowhidpi flag, setting glass.win.uiScale to 100% did the trick to ignore Windows scaling. This worked setting it in code and passing it as an argument.

    public class Main {
        public static void main(String[] args) {
            System.setProperty("glass.win.uiScale", "100%"); // instead of allowhidpi
            MainFXML.run(args);
        }
    }
    

    Be warned that setting prism.allowhidpi to false will negate the scaling override from what I tested.