javamacosmacos-catalinamacos-darkmode

Java 8 application not working correctly with dark mode on MacOS Catalina 10.15


If the user switches System Preferences:General:Appearance to Dark the main screen (a JFrame) of my application goes from

enter image description here

to

enter image description here

So clearly Java recognises that Dark mode has been selected but doesn't do a very good job of adjusting accordingly. The most pressing issue is that the text colour needs to be changed from black to white but there are other issues as well.

I am using the latest version of Java 8 (jdk1.8.0_231.jdk), not in position to move to Java 13 yet but from the release notes sounds like they still have problems with Dark mode.

Is there an established way to fix this Im not sure of the best approach.

Also its worth noting the other pages which subclass JDialog dont change to black (apart from menubar so still readable but looking out of place)

e.g goes from

enter image description here

to

enter image description here

Made a start with UIDefaults

public static boolean isDarkModeEnabled()
    {

        try
        {
            // check for exit status only. Once there are more modes than "dark" and "default", we might need to analyze string contents..
            final Process proc = Runtime.getRuntime().exec(new String[]{"defaults", "read", "-g", "AppleInterfaceStyle"});
            proc.waitFor(100, TimeUnit.MILLISECONDS);
            boolean result = proc.exitValue() == 0;
            MainWindow.logger.severe("Is Dark Mode:" + result);
            return result;
        }
        catch (IOException | InterruptedException | IllegalThreadStateException ex)
        {
            // IllegalThreadStateException thrown by proc.exitValue(), if process didn't terminate
            MainWindow.logger.severe("Unable to determine dark mode");
            return false;
        }

public static void displayAsDarkMode()
{
    Color whitish       = new Color(250,250, 250);
    Color fadedWhite    = new Color(200,200, 200);
    Color lightGray     = new Color(49,52, 56);
    Color darkGray      = new Color(30,34,38);

    UIManager.put("Label.foreground", whitish);
    UIManager.put("Panel.background", lightGray);
    UIManager.put("CheckBox.textForeground", whitish);
    UIManager.put("CheckBox.foreground", whitish);
    UIManager.put("TextField.background", darkGray);
    UIManager.put("TextField.foreground", whitish);
    UIManager.put("ComboBox.foreground", darkGray);
    UIManager.put("ComboBox.textForeground", whitish);
    UIManager.put("Button.background", lightGray);
    UIManager.put("Button.textForeground", fadedWhite);
    UIManager.put("List.background", darkGray);
    UIManager.put("List.foreground", whitish);
    UIManager.put("TextArea.background", darkGray);
    UIManager.put("TextArea.inactiveBackground", darkGray);
    UIManager.put("Table.background", darkGray);
    UIManager.put("Table.gridColor", lightGray);
}

but I know Im not the first person to hit this problem


Solution

  • It looks like Sun is working on this and may have it ready for Java 14, but not working properly currently.

    https://bugs.openjdk.java.net/browse/JDK-8231438

    I had some success by setting UIManager colours but problem remain such as appears impossible to change the colour of a ComboBox or Button from white if using Aqua L&F

    there are alternative user made L&Feels such as Darcula and VAqua but these bring their own problems.

    So I will probably make do with my partial UIManager approach until Oracle properly fix things.