import java.awt.Canvas; 
import java.awt.FlowLayout; 
import java.awt.Image; 
import java.awt.MediaTracker; 
import java.awt.Toolkit; 
import java.awt.image.BaseMultiResolutionImage; 
import java.net.URL; 
import java.util.Arrays; 
import javax.swing.Icon; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

/* 
    Demonstration of an "Invalid Image variant" exception when attempting to use a 
    MultiResolutionImage on Windows 10 on Java 10.0.2, 11-ea, or 12-ea. 

      Setup: 
      * Windows 10 
      * OpenJDK 10.0.2. 
      * One HiDPI laptop screen set at scaling "200%" in the Windows "Display" settings app, 
        combined with a regular non-HiDPI external monitor as the main display. 
        (Tested on a Lenovo X1 Carbon 6th gen laptop.) 

      The situation in which the bug was consistently encountered was as follows: 
      1) Start this application. The JFrame will appear on the primary monitor. The icon in the 
         button says "ICON 1x". 
      2) Now drag the Window over to the HiDPI screen. An exception occurs. 
         (see stack trace attached to this bug report.) 
*/ 
public class InvalidImageVariantBugExhibit { 
  public static void main(String[] args) { 
    System.out.println("Java Version: " + System.getProperty("java.version")); 
    SwingUtilities.invokeLater(InvalidImageVariantBugExhibit::onEDT); 
  } 

  private static Image loadImage(String resourceName) { 
    URL url = InvalidImageVariantBugExhibit.class.getResource(resourceName); 
    if (url == null) 
      throw new RuntimeException("Could not find resource URL for " + resourceName); 
    Image ret = Toolkit.getDefaultToolkit().getImage(url); 
    if (ret == null) 
      throw new RuntimeException("Failed to load image " + url); 
    /* Commenting out this may cause the "Invalid Image variant" exception to be thrown even when 
    "button.setEnabled(false)" is omitted. It may also cause incorrect icon positioning even on 
    regular non-HiDPI displays, as shown in the screenshot in 
    WrongIconPositionIfNotWaitingForImageToLoad.png. */ 
    waitForImage(ret); 
    return ret; 
  } 

  private static void waitForImage(Image image) { 
    final MediaTracker mt = new MediaTracker(new Canvas()); 
    mt.addImage(image, 0); 
    try { 
      mt.waitForAll(); 
    } catch (InterruptedException e) { 
      throw new RuntimeException("Unexpected interrupt ", e); 
    } 
    if (mt.isErrorAny()) { 
      throw new RuntimeException("Unexpected MediaTracker error " + 
          Arrays.toString(mt.getErrorsAny())); 
    } 
  } 

  private static void onEDT() { 
    try { 
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
    } catch (ClassNotFoundException | IllegalAccessException | 
        InstantiationException | UnsupportedLookAndFeelException e) 
    { 
      throw new RuntimeException(e); 
    } 

    JFrame frame = new JFrame(); 
    frame.setSize(300, 100); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    JPanel panel = new JPanel(new FlowLayout()); 

	Image img1x = loadImage("icon_single_size.png"); 
    Image img2x = loadImage("icon_double_size.png"); 
	BaseMultiResolutionImage mri = new BaseMultiResolutionImage(new Image[] { img1x, img2x }); 
    Icon icon = new ImageIcon(mri); 

    JButton button = new JButton(); 
    button.setIcon(icon); 
    button.setText("Test Button"); 
    button.setEnabled(false); 
    panel.add(button); 

    frame.getContentPane().add(panel); 
    frame.setVisible(true); 
  } 
} 