1

I have two versions of an image: logo.png (265x150) and logo@2x.png (530x300). The second one is the retina-version.

In my Java application I have a JLabel on which I'm setting the background to an image like so:

contentPane = new JPanel();
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setBackground(Color.WHITE);
lblNewLabel.setBounds(9, 6, 265, 150);
lblNewLabel.setIcon(new ImageIcon("login_logo.png"));
contentPane.add(lblNewLabel);

This works fine, but I'm not sure how to display the retina-version properly on my Macbook Pro Retina. The retina image isn't scaled resulting in an image that is only partially visible.

Kara
  • 6,115
  • 16
  • 50
  • 57
Jeffrey
  • 1,239
  • 8
  • 15
  • So you want to detect if you're running on a computer with a retina display. That's your real question isn't it? – Robin Green Dec 01 '13 at 18:04
  • 1
    @RobinGreen No, I need a proper way to display a (retina) image on a retina display. – Jeffrey Dec 01 '13 at 18:08
  • A png file for a retina display is fundamentally no different from any other png file. There are only images that are designed for retina displays. So I don't understand what your problem is. Why can't you just change the filename? – Robin Green Dec 01 '13 at 18:14
  • Simply changing the filename won't do the trick. The retina image isn't scaled resulting in an image that is only partially visible. – Jeffrey Dec 01 '13 at 18:39
  • Aha! And now, finally, you reveal *what your real problem is*. Wouldn't it have been less effort for everyone involved if you had mentioned that upfront? But this still isn't enough detail. When does this happen? Show the code. – Robin Green Dec 01 '13 at 18:40
  • @RobinGreen What else would you like to know? I'm not sure what other details I could provide – Jeffrey Dec 01 '13 at 18:43
  • The actual code. Preferably as much as possible. For example, are you calling `setSize` or using a layout manager? Are you dynamically replacing the image? – Robin Green Dec 01 '13 at 18:43
  • 1
    While it's fun to see this back and forth, and a learning experience, no doubt, how about a solution that is a bit more generic? I have a high resolution display, and would appreciate you not displaying the lesser resolution file on my display just because I run Linux. – Edwin Buck Dec 01 '13 at 18:47
  • possible duplicate of http://stackoverflow.com/questions/12431148/swing-and-bitmaps-on-retina-displays – Robin Green Dec 01 '13 at 19:13

3 Answers3

0

My personal opinion would be, first check for retina display, then set the image

 Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor")

The above line will return 2.0 on retina displays. On non-retina macs it will returns 1.0 and on all other platforms null

try following code

public boolean isRatinaDisplay(){
    boolean isRatina = false;
    if (null != Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor") && Float.parseFloat((String) Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor")) == 2.0) {
       //The above line will return 2.0 on retina displays. 
       //On non-retina macs it will returns 1.0 and on all other platforms null
       isRatina = true;
    }
}
JLabel lblLabel = new JLabel("");
if(isRatinaDisplay()){ //if mac set ratina image
  lblLabel.setIcon(new ImageIcon("logo@2x.png"));
  lblLabel.setSize(new Dimension(530,300));
  lblLabel.setBounds(9, 6, 530,300);
}else{ //else normal
  lblLabel.setSize(new Dimension(265, 150));
  lblLabel.setIcon(new ImageIcon("logo.png"));
  lblLabel.setBounds(9, 6, 265, 150);
}
Shamse Alam
  • 1,285
  • 10
  • 21
0

I think, that you are using two images in different sizes/resolutions. A small one for a display with small resolutions and a bigger one for displays with higher resolution.

A retina display differs from other display essentially in its higher resolution.

So you could try to find out the display resolution and check it that matches to the retina display. There are several possibilities to do that. One could be this: How do you get the screen width in java?

But maybe it would be better to use the size of your JFrame, since that can be in fullscreenmode, or smaller, and the user can change that, as long as you allow that. The size of your JFrame can be determined by this: http://docs.oracle.com/javase/6/docs/api/java/awt/Component.html#getSize()

Another thought: In near future there will be more companies then just apple that provide displays in that solution.

Greetings!

Community
  • 1
  • 1
treeno
  • 2,510
  • 1
  • 20
  • 36
  • This wasn't my question; I know very well what a retina display is. The point is: I need to properly display the high-res image (retina version!) in my JLabel component. – Jeffrey Dec 01 '13 at 18:38
  • @Jeffrey You seem to have the attitude that we are all missing the point. I think the reverse is true. I think you need to slow down, take a deep breath, and read what we are saying more carefully. – Robin Green Dec 01 '13 at 18:39
  • @Jeffrey: Could you explain what exactly a retina-version of a png is? I think this is what I am missing... – treeno Dec 01 '13 at 19:50
  • @Jeffrey: What do you mean by "propery display"? – treeno Dec 01 '13 at 19:57
  • Ah, sorry... I if I understand it correctly now, you could try to call doLayout() on the Container that is the parent of the JLabel. That should relayout the Container and all it's children, so that the size of the children will be recalculated. But this would only make sense if you change the image after the initial creation of the dialog... – treeno Dec 01 '13 at 20:02
  • If you don't change the Image after the initial creation of the dialog. you might have a problem with the layoutmanager. Maybe the LayoutManager doesn't allow the Label to grow. – treeno Dec 01 '13 at 20:08
0

The image is bigger (in terms of width and height in pixels, not in inches) so the JLabel needs to be made bigger (setBounds takes arguments that are measured in pixels, not in inches. This is not actually documented in the Javadocs but it is obvious when you check the Javadocs for setSize).

Java "pixels" aren't real pixels on Apple retina displays. See Swing and bitmaps on retina displays

Also, according to this answer only certain versions of Java support retina displays. I don't know if that's relevant to your problem.

Community
  • 1
  • 1
Robin Green
  • 32,079
  • 16
  • 104
  • 187
  • When properly displayed, the size in inches is indeed the same, but it's not properly displayed so it's still twice the size (in both pixels and inches). As far as I can tell ``setSize`` takes pixels as arguments. – Jeffrey Dec 01 '13 at 19:07
  • According to [this answer](http://stackoverflow.com/questions/15181079/apple-retina-display-support-in-java-jdk-1-7-for-awt-swing) only certain versions of Java support retina displays. I don't know if that's relevant to your problem. – Robin Green Dec 01 '13 at 19:11
  • Other components such as JLabel are displaying fine, so the Java version is not the issue here. – Jeffrey Dec 01 '13 at 19:12