Kitswas
Kitswas

Reputation: 1197

Change system look and feel theme

I know I can set System L&F using

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

and change the theme for a certain L&F (say, "Metal") using

MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme());

Is there a way to change the theme (light/dark) for the System Look and Feel?

System Default (On Windows) Light

System Dark (What I wish to achieve)Dark

I want the dark theme of the System L&F.

If a dark theme does not exist, I wish to invert the colours of the default theme.

Upvotes: 4

Views: 4473

Answers (1)

TriS
TriS

Reputation: 4038

To change the system look and feel we have to understand how the current implementation of UIManager.getSystemLookAndFeelClassName() works.

The code in javax.swing.UIManager is

 public static String getSystemLookAndFeelClassName() {
        String systemLAF = AccessController.doPrivileged(
                             new GetPropertyAction("swing.systemlaf"));
        if (systemLAF != null) {
            return systemLAF;
        }
        OSInfo.OSType osType = AccessController.doPrivileged(OSInfo.getOSTypeAction());
        if (osType == OSInfo.OSType.WINDOWS) {
            return "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
        } else {
            String desktop = AccessController.doPrivileged(new GetPropertyAction("sun.desktop"));
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            if ("gnome".equals(desktop) &&
                    toolkit instanceof SunToolkit &&
                    ((SunToolkit) toolkit).isNativeGTKAvailable()) {
                // May be set on Linux and Solaris boxs.
                return "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
            }
            if (osType == OSInfo.OSType.MACOSX) {
                if (toolkit.getClass() .getName()
                                       .equals("sun.lwawt.macosx.LWCToolkit")) {
                    return "com.apple.laf.AquaLookAndFeel";
                }
            }
            if (osType == OSInfo.OSType.SOLARIS) {
                return "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
            }
        }
        return getCrossPlatformLookAndFeelClassName();
    }

Now for Windows it gets its data from com.sun.java.swing.plaf.windows.WindowsLookAndFeel . You can find more information about the class in this link (Open Jdk WindowsLookAndFeel.java).

The link clearly says "Implements the Windows95/98/NT/2000 Look and Feel". Package name starts with "com.sun.java.swing". I guess chances for getting updates might be meagre and your system might have higher windows version.

To solve your issue we can use many ways

  1. Create a new class then extend the above class and override the methods. Then you can change default colors.

  2. By using Synth—the basis for creating your own look and feel with an XML file.

  3. Use Nimbus. As it is very easy to customize it. Some info on how to use Nimbus.
    You can use it to set in UIManager.setLookAndFeel object.

    try { 
        UIManager.put( "control", new Color( 0, 0, 0) );
        UIManager.put( "Button.background", new Color(18, 30, 49) );
        UIManager.put( "Button.foreground", new Color( 59, 68, 75) );
        UIManager.put( "info", new Color(128,128,128) );
        UIManager.put( "nimbusBase", new Color( 18, 30, 49) );
        UIManager.put( "nimbusAlertYellow", new Color( 248, 187, 0) );
        UIManager.put( "nimbusDisabledText", new Color( 128, 128, 128) );
        UIManager.put( "nimbusFocus", new Color(115,164,209) );
        UIManager.put( "nimbusGreen", new Color(176,179,50) );
        UIManager.put( "nimbusInfoBlue", new Color( 66, 139, 221) );
        UIManager.put( "nimbusLightBackground", new Color( 18, 30, 49) );
        UIManager.put( "nimbusOrange", new Color(191,98,4) );
        UIManager.put( "nimbusRed", new Color(169,46,34) );
        UIManager.put( "nimbusSelectedText", new Color( 255, 255, 255) );
        UIManager.put( "nimbusSelectionBackground", new Color( 104, 93, 156) );
        UIManager.put( "text", new Color( 255, 255, 255) );
        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                break;
            }
        }    
    } catch (Exception e) {
        System.err.println("Exception caught:"+e);               
    } 
    

Few more information to customize it.

Upvotes: 2

Related Questions