JDK-8156182 : [macosx] HiDPI/Retina icons do not work for disabled JButton/JMenuItem etc.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 8u92,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: os_x
  • CPU: x86
  • Submitted: 2016-04-29
  • Updated: 2016-09-08
  • Resolved: 2016-08-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b135Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Darwin localhost 13.4.0 Darwin Kernel Version 13.4.0: Mon Jan 11 18:17:34 PST 2016; root:xnu-2422.115.15~1/RELEASE_X86_64 x86_64

EXTRA RELEVANT SYSTEM CONFIGURATION :
MacBook Air 13-inch Mid 2012. (Retina mode can be enabled for testing purposes even on the non-retina MacBooks; see http://www.tekrevue.com/tip/hidpi-mode-os-x/ .)

A DESCRIPTION OF THE PROBLEM :
Bug JDK-8011059 added support for retina/HiDPI icons via MultiResolutionImage and the "@2x" postfix on images loaded for instance via the ImageIcon(URL) constructor. When turning retina on or off from the "Displays" preferences, or dragging a JFrame between a retina and a non-retina screen, Swing correctly picks the correct image file to display, picking the file with the "@2x" postfix for retina screens. However, if the image is used in a disabled JButton or JMenuItem (and probably similar other places), the lower-resolution variant is always used (grayed out).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
On a MacOS machine with a retina display enabled, run the attached code sample. There should be two images named "icon.png" and "icon@2x.png" in the same directory as RetinaBugExhibitJFrame.java; the first one can be any 16x16 image while the second one can be any 32x32 image (I suggest making them look different to see which one is being used).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When the JFrame is displayed on a retina-enabled display, the JButton should show a grayed-out version of "icon@2x.png".
ACTUAL -
When the JFrame is displayed on a retina-enabled display, the JButton instead shows a grayed-out version of a scaled-up "icon.png". Note that if "button.setEnabled(false);" is commented out, the correct "icon@2x.png" file is used for retina-enabled displays.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.net.URL;
import javax.swing.*;

public final class RetinaBugExhibitJFrame extends JFrame {
  private final JButton button = new JButton("Button");

  public static void main(String args[]) {
    SwingUtilities.invokeLater(() -> { new RetinaBugExhibitJFrame().setVisible(true); });
  }

  public RetinaBugExhibitJFrame() {
    URL url = Thread.currentThread().getContextClassLoader().getResource("icon.png");
    getContentPane().add(button, java.awt.BorderLayout.SOUTH);
    button.setIcon(new ImageIcon(url));
    button.setEnabled(false);
    pack();
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Might be able to use JButton.setDisabledIcon to set an explicit disabled icon. But all icons would then need to be produced in gray and non-gray versions.


Comments
The proposed fix: http://cr.openjdk.java.net/~alexsch/8151303/webrev.02/
29-06-2016