9

I downloaded and installed the latest Java 9 early access version, and was delighted to find that a Java Swing application on Windows now renders components at the correct size. No longer do my customers with HiDPI displays need to use my app at half the intended width and height.

However I noticed that in my Swing application, my own icons are simply being scaled to double the width and height, making them look jaggy.

I do have a full set of all icons at both normal size (eg foobar.png) and at double width/height (eg foobar@2x.png). I use the Apple naming conventions.

How would I go about getting Java 9 to easily find and use the higher resolution version of an image when it is available, without having to manually code for this?

A code sample always makes a question clearer, so does Java 9 have a multi-resolution icon class that I could use to make the following code compile and run?

import javax.swing.*;

public class ScratchSpace {

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("I work in HiDPI!");

            // can I replace the following line with some magical new method that automatically loads the same icon at multiple resolutions
            // so that Swing chooses the correct one when rendering, depending on the current scale of the current display?
            Icon icon = new IconWithMultipleSizes("foobar.png");

            JLabel label = new JLabel("I'm a label with an icon.", icon, SwingConstants.LEFT);
            frame.setContentPane(label);

            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

I think there must be such a class, but I can't find it.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Steve McLeod
  • 51,737
  • 47
  • 128
  • 184

2 Answers2

2

After perusing the Java 9 source code, my conclusion is that although a MultiResolutionImage class exists in the Java API, it is not yet being used by java.awt.Toolkit on Windows. The code for creating instances of Java 9 MultiResolutionImage is present on the OS X-specific instance of java.awt.Toolkit.

My assumption is that this is still on Oracle's todo list as part of adding HiDPI support to Java 9.

Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
  • The current docs for BaseMultiResolutionImage appear to imply that it somehow looks at the DPI of the graphics object it's being drawn into and chooses the smallest usable image, but how it uses the graphics object to do this is not yet clear to me. – Hakanai Oct 19 '17 at 04:03
1

In this section of OpenJDK describes an API for java.awt.image. java.awt.Graphics is meant to retrieve the right based on the DPI metrics.

Until then I guess you could check for a DPI scale factor, then draw the image with the resolution of that DPI scale. But that'd be frustrating.

However, it looks like this other page has a class that might be able to differentiate between multi resolution images, you'd just have to import it.

I'm still looking into that second link to see how I can get it to work, but it looks promising.

S. Zipkin
  • 11
  • 1