All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.actelion.research.gui.hidpi.HiDPIHelper Maven / Gradle / Ivy

There is a newer version: 2024.12.1
Show newest version
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 COLOR1_BRIGHT_LAF = 0x00503CB4;	// main button color in supplied images
	private static final int COLOR2_BRIGHT_LAF = 0x00000000;	// second button color in supplied images

	private static final int COLOR1_DARK_LAF = 0x00B4A0FF;	// main button color in supplied images
	private static final int COLOR2_DARK_LAF = 0x00E0E0E0;	// second button color in supplied images

	private static final float ICON_SCALE_LIMIT = 1.2f; // custom dpi scale factors smaller than this will be neglected

	// 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 (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) {}

		return sRetinaFactor;
		}

	/**
	 * For Windows and Linux this method returns the user defined UI scaling factor.
	 * On Windows this is done by judging by 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. 
* If a Java system property 'dpifactor' is defined, its value is used rather than * a font size derived one.
* On the Macintosh this factor is usually 1.0, because HiDPI device support uses * a diffewrent mechanism (see getRetinaScaleFactor()). * @return typically 1.0 or 1.25, 1.5, ... */ public static float getUIScaleFactor() { if (sUIScaleFactor == -1) { sUIScaleFactor = Platform.isWindows() ? (float) UIManager.getFont("Label.font").getSize() / 13f : 1f; if (System.getProperty("dpifactor") != null) { try { sUIScaleFactor = Float.parseFloat(System.getProperty("dpifactor")); } catch (NumberFormatException nfe) {} } } 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 Icon createIcon(String fileName, int rotation) { return new HiDPIIcon(scale(rotate(createLaFCompatibleImage(fileName), rotation))); } public static Icon createDisabledIcon(String fileName, int rotation) { return new HiDPIIcon(scale(rotate(createDisabledImage(fileName), rotation))); } 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) fileName = getDoubleResolutionFileName(fileName); URL url = HiDPIIconButton.class.getResource("/images/" + fileName); if (url == null) throw new RuntimeException("Could not find: " + fileName); try { BufferedImage image = ImageIO.read(url); return image; } catch (IOException ioe) { return null; } } /** * Creates an image from the fileName. On HiDPI devices this is a high * resolution image. If the current look&feel is dark, then colors are adapted * for optimal contrast. * @param fileName * @return */ public static BufferedImage createLaFCompatibleImage(String fileName) { BufferedImage image = createImage(fileName); if (image != null && LookAndFeelHelper.isDarkLookAndFeel()) brightenImage(image); return image; } private static BufferedImage createDisabledImage(String fileName) { BufferedImage image = createLaFCompatibleImage(fileName); Color gray = LookAndFeelHelper.isDarkLookAndFeel() ? ColorHelper.brighter(UIManager.getColor("Panel.background"), 0.8f) : ColorHelper.darker(UIManager.getColor("Panel.background"), 0.8f); int grayRGB = 0x00FFFFFF & gray.getRGB(); for (int x=0; x ICON_SCALE_LIMIT) // in this case we have double size images return image.getScaledInstance(Math.round(0.5f * scale * image.getWidth()), Math.round(0.5f * scale * image.getHeight()), Image.SCALE_SMOOTH); else return image; } private static void brightenImage(BufferedImage image) { for (int x=0; x




© 2015 - 2025 Weber Informatics LLC | Privacy Policy