com.actelion.research.gui.hidpi.HiDPIHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
package com.actelion.research.gui.hidpi;
import com.actelion.research.gui.LookAndFeelHelper;
import com.actelion.research.util.ColorHelper;
import com.actelion.research.util.Platform;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
public class HiDPIHelper {
private static final int THEME_COLOR1_BRIGHT_LAF = 0x00503CB4; // main button color in supplied images
private static final int THEME_COLOR2_BRIGHT_LAF = 0x00000000; // second button color in supplied images
private static final int THEME_COLOR1_DARK_LAF = 0x00B4A0FF; // main button color in supplied images
private static final int THEME_COLOR2_DARK_LAF = 0x00E0E0E0; // second button color in supplied images
private static final float ICON_SCALE_LIMIT_1 = 1.1f; // custom dpi scale factors smaller than this will be neglected
private static final float ICON_SCALE_LIMIT_2 = 1.9f; // custom dpi scale factors between ICON_SCALE_LIMIT_2 and ICON_SCALE_LIMIT_3
private static final float ICON_SCALE_LIMIT_3 = 2.1f; // use larger image, but won't be scaled
// This is an Apple only solution and needs to be adapted to support high-res displays of other vendors
private static float sRetinaFactor = -1f;
private static float sUIScaleFactor = -1f;
/**
* Macintosh retina display support for Java 7 and newer.
*
* @return 1.0 on standard resolution devices and 2.0 for retina screens
*/
public static float getRetinaScaleFactor() {
/* with Apple-Java-6 this was:
Object sContentScaleFactorObject = Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor");
private static final float sRetinaFactor = (sContentScaleFactorObject == null) ? 1f : ((Float)sContentScaleFactorObject).floatValue();
*/
if (Platform.isMacintosh()) {
if (sRetinaFactor != -1f)
return sRetinaFactor;
sRetinaFactor = 1f;
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
final GraphicsDevice device = env.getDefaultScreenDevice();
try {
Field field = device.getClass().getDeclaredField("scale");
if (field != null) {
field.setAccessible(true);
Object scale = field.get(device);
if (scale instanceof Integer)
sRetinaFactor = (Integer) scale;
else
System.out.println("Unexpected content scale (not 1 nor 2): " + scale.toString());
}
} catch (Throwable e) {
}
/* the above code gives WARNING under Java 9:
WARNING: An illegal reflective access operation has occurred
WARNING: All illegal access operations will be denied in a future release
If we know, we are on a Mac, we could do something like:
if (device instanceof CGraphicsDevice) { // apple.awt.CGraphicsDevice
final CGraphicsDevice cgd = (CGraphicsDevice)device;
// this is the missing correction factor, it's equal to 2 on HiDPI a.k.a. Retina displays
final int scaleFactor = cgd.getScaleFactor();
// now we can compute the real DPI of the screen
final double realDPI = scaleFactor * (cgd.getXResolution() + cgd.getYResolution()) / 2;
}*/
} else {
GraphicsDevice sd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
sRetinaFactor = (float) sd.getDefaultConfiguration().getDefaultTransform().getScaleX();
}
return sRetinaFactor;
}
/**
* For Windows and Linux this method returns the user defined UI scaling factor.
* This is done by judging from the size of the UIManager's Label.font
* and comparing it to the unscaled default (13). Typically this factor is larger
* than 1.0 on HiDPI devices. For this method to work the Look&Feel must consider
* the OS provided setting and scale its fonts accordingly (Substance LaF does).
* On the Macintosh this factor is usually 1.0, because HiDPI device support uses
* a different mechanism (see getRetinaScaleFactor()).
* @return typically 1.0 or 1.25, 1.5, ...
*/
public static float getUIScaleFactor() {
if (sUIScaleFactor == -1) {
if (getRetinaScaleFactor() != 1f)
sUIScaleFactor = 1f;
else
sUIScaleFactor = Platform.isMacintosh() ? 1f : (float) UIManager.getFont("Label.font").getSize() / 12f;
//System.out.println("HiDPIHelper.getUIScaleFactor() retina:"+sRetinaFactor+" UI:"+sUIScaleFactor);
}
return sUIScaleFactor;
}
/**
* This is a convenience method that scales the passed int value with getUIScaleFactor()
* and returns the rounded result.
* @param value
* @return
*/
public static int scale(int value) {
return Math.round(getUIScaleFactor() * value);
}
/**
* This is a convenience method that scales the passed int value with getUIScaleFactor()
* and with getRetinaScaleFactor() and returns the rounded result.
* @param value
* @return
*/
public static int scaleRetinaAndUI(int value) {
return Math.round(getUIScaleFactor() * getRetinaScaleFactor() * value);
}
public static Color getThemeColor(int no) {
int c = (no == 0) ?
(LookAndFeelHelper.isDarkLookAndFeel() ? THEME_COLOR1_DARK_LAF : THEME_COLOR1_BRIGHT_LAF)
: (LookAndFeelHelper.isDarkLookAndFeel() ? THEME_COLOR2_DARK_LAF : THEME_COLOR2_BRIGHT_LAF);
return new Color(c);
}
public static Icon createIcon(String fileName, int rotation) {
BufferedImage image = capCorners(rotate(createLaFCompatibleImage(fileName), rotation));
boolean isScaled = mustScale();
return new HiDPIIcon(isScaled ? scale(image) : image, isScaled);
}
public static Icon createDisabledIcon(String fileName, int rotation) {
BufferedImage image = capCorners(rotate(createDisabledImage(fileName), rotation));
boolean isScaled = mustScale();
return new HiDPIIcon(isScaled ? scale(image) : image, isScaled);
}
private static String getDoubleResolutionFileName(String fileName) {
int index = fileName.lastIndexOf('.');
return fileName.substring(0, index).concat("@2x").concat(fileName.substring(index));
}
private static BufferedImage rotate(BufferedImage image, int rotation) {
int size = image.getHeight();
int max = size-1;
if (rotation == 90) {
for (int x=0; x ICON_SCALE_LIMIT_1;
}
private static boolean mustScale() {
return (getUIScaleFactor() * getRetinaScaleFactor() > ICON_SCALE_LIMIT_1
&& getUIScaleFactor() * getRetinaScaleFactor() < ICON_SCALE_LIMIT_2)
|| getUIScaleFactor() * getRetinaScaleFactor() < ICON_SCALE_LIMIT_3;
}
public static float getIconScaleFactor() {
if (!mustScale())
return 1f;
float scale = getUIScaleFactor() * getRetinaScaleFactor();
if (useDoubleImage())
scale *= 0.5f;
return scale;
}
public static Image scale(BufferedImage image) {
float scale = getIconScaleFactor();
return image.getScaledInstance(Math.round(scale * image.getWidth()),
Math.round(scale * image.getHeight()), Image.SCALE_SMOOTH);
}
private static BufferedImage capCorners(BufferedImage image) {
image.setRGB(0, 0, 0x00000000);
image.setRGB(1, 0, 0x00000000);
image.setRGB(0, 1, 0x00000000);
image.setRGB(image.getWidth()-2, 0, 0x00000000);
image.setRGB(image.getWidth()-1, 0, 0x00000000);
image.setRGB(image.getWidth()-1, 1, 0x00000000);
image.setRGB(0, image.getHeight()-1, 0x00000000);
image.setRGB(1, image.getHeight()-1, 0x00000000);
image.setRGB(0, image.getHeight()-2, 0x00000000);
image.setRGB(image.getWidth()-2, image.getHeight()-1, 0x00000000);
image.setRGB(image.getWidth()-1, image.getHeight()-1, 0x00000000);
image.setRGB(image.getWidth()-1, image.getHeight()-2, 0x00000000);
return image;
}
private static void brightenImage(BufferedImage image) {
for (int x=0; x
© 2015 - 2025 Weber Informatics LLC | Privacy Policy