Reputation: 1197
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 Dark (What I wish to achieve)
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
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
Create a new class then extend the above class and override the methods. Then you can change default colors.
By using Synth—the basis for creating your own look and feel with an XML file.
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