-1

In the company where I work, we derived a class from sun.awt.WToolkit to change some of the colors by calling setDesktopProperty(). And that worked fine for years. But now in JDK 8, WToolkit is final and cannot be subclassed. The easy way out could be doing some nasty reflection and call the protected method, though I'm not sure that this won't yield a security exception or something similar.

The right way out is to change these colors through the Look and Feel. Oracle in Windows Desktop Property Support states that

Programs do not need to access these properties directly; the Windows look and feel will automatically read and interpret these properties to provide proper visuals and behavior for the components.

But it does not state anything about customizing these properties through LaF modifications and certainly doing UIManager.put("win.3d.shadowColor", Color.gray); as it's mentioned in this doc is ineffective.

So my question is, can Windows Desktop Properties be changed by subclassing an existing Look and Feel, or should I resort to some kind of a hack?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Stelios Adamantidis
  • 1,866
  • 21
  • 36
  • Question: you seem to be using System L&F and patched the color via that trick? The Nimbus (or any other) L&F should pose no problem. May SystemColor constants be a help? – Joop Eggen Mar 06 '15 at 07:53
  • @JoopEggen I'm using Windows LaF. I can't see any use of SystemColor in that particular problem. Can you please elaborate? – Stelios Adamantidis Mar 06 '15 at 08:09
  • 1
    Why is `UIManager.put` “ineffective”? – Holger Mar 06 '15 at 08:11
  • @Holger because it doesn't change the particular color like the `setDesktopProperty()` used to do? – Stelios Adamantidis Mar 06 '15 at 08:12
  • 2
    What do you want to achieve? If you want to change the color that the look&feel will use, it is the right place. Of course, you have to do it at the right time, after installing the look&feel but before creating components… – Holger Mar 06 '15 at 08:16
  • Windows LaF is the system's LaF. SystemColor with for instance `SystemColor.desktop`. You could copy colors, switch to a crossplatform LaF (Nimbus) and use those Windows colors, patched as needed, The crossplatform Look-and-Feels are easily themed (using UIDefaults or so). – Joop Eggen Mar 06 '15 at 08:19
  • @Holger I want to change the colors imposed by the theme. "win.*.*" are not LaF properties as described in Windows Desktop Property Support that I liked in the question. – Stelios Adamantidis Mar 06 '15 at 08:25
  • @JoopEggen understandable but implies a bigger development effort. Besides, LaF is collateral damage, we are forced to JDK8 for security reasons. – Stelios Adamantidis Mar 06 '15 at 08:25
  • I fully understand - reflection was a "nice" idea for a fast hack. I hope that was the only damage found. – Joop Eggen Mar 06 '15 at 08:51

1 Answers1

3

Swing’s Windows Look&Feel will import the Window-specific desktop properties into its defaults table, but within this table, the standard, LaF-independent names are used which are usually composed from the component’s name and the property.

E.g.:

try {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException|InstantiationException
        |IllegalAccessException|UnsupportedLookAndFeelException ex) {
    Logger.getLogger(LaFColors.class.getName()).log(Level.SEVERE, null, ex);
    System.exit(1);
}
UIManager.put("Panel.background", Color.YELLOW);
UIManager.put("Button.foreground", Color.BLUE);
JFrame frame=new JFrame("Test");
frame.getContentPane().add(new JButton("See, it’s still "
   +UIManager.getLookAndFeel().getName()+" LaF"), BorderLayout.NORTH);
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Holger
  • 285,553
  • 42
  • 434
  • 765
  • So what you actually suggest is let the LaF read the `win.*` properties and then use the LaF properties to change what you want. I admit this is the closest to what I want. But there is a pitfall though: The equivalent of setting "win.item.highlightColor" would be to set all relevant "Component.selectionBackground" properties. Thanks to @camickr UIManager Defaults that's easier than it sounds. But that imposes more testing so maybe the reflection solution will prevail... – Stelios Adamantidis Mar 06 '15 at 09:23
  • When Windows LaF is used, some parts of components are painted using Windows Theming API: for example, the background of JTabbedPane. Windows Classic LaF is easier to customize because all the colors are stored in UIManager. – Alexey Ivanov May 05 '15 at 15:19