com.github.swingdpi.UiDefaultsScaler Maven / Gradle / Ivy
/*
* Copyright 2016 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* This project is hosted at: https://github.com/lukeu/swing-dpi
* Comments & collaboration are both welcome.
*/
package com.github.swingdpi;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.util.Collections;
import java.util.IdentityHashMap;
import javax.swing.Icon;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import com.github.swingdpi.plaf.BasicTweaker;
import com.github.swingdpi.plaf.MetalTweaker;
import com.github.swingdpi.plaf.NimbusTweaker;
import com.github.swingdpi.plaf.Tweaker;
import com.github.swingdpi.plaf.WindowsTweaker;
/**
* Applies changes to Swing's {@code UIDefaults} to perform a best-effort default scaling for many
* parts of the UI, according to a specified scaling percentage.
*
* A few other tweaks are made at the same time, to adjust the UI metrics to reflect more modern
* practices, like table and tree row sizing on all platforms and changing the Windows UI font to be
* more like Windows 7, less like Windows 95.
*
* For example, see internal comments of JDK class {@code BasicTableUI#installDefaults}
* about how Sun realised that table-row heights were incorrect on each platform, but it became
* too risky to change them after release.
*/
public class UiDefaultsScaler {
private final Tweaker delegate;
private UiDefaultsScaler(Tweaker delegate) {
this.delegate = delegate;
}
public static void updateAndApplyGlobalScaling(int scalingInPercent, boolean alsoTweak) {
float scaleFactor = scalingInPercent / 100f;
BasicTweaker tweaker = createTweakerForCurrentLook(scaleFactor);
tweaker.setDoExtraTweaks(alsoTweak);
UiDefaultsScaler scaler = new UiDefaultsScaler(tweaker);
scaler.applyScalingAndTweaks();
// Updates the global constant, which can be used for apply scaling to UI elements not
// covered by the UIDefaults. This also fires a notification event to anyone interested.
UiScaling.setScaling(scalingInPercent);
}
private void applyScalingAndTweaks() {
delegate.initialTweaks();
modifyDefaults(delegate);
delegate.finalTweaks();
}
private static BasicTweaker createTweakerForCurrentLook(float dpiScaling) {
String testString = UIManager.getLookAndFeel().getName().toLowerCase();
if (testString.contains("windows")) {
return new WindowsTweaker(dpiScaling, testString.contains("classic"));
}
if (testString.contains("metal")) {
return new MetalTweaker(dpiScaling);
}
if (testString.contains("nimbus")) {
return new NimbusTweaker(dpiScaling);
}
return new BasicTweaker(dpiScaling);
}
private void modifyDefaults(Tweaker tweaker) {
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
// Used to replicate aliased-references to the same object wherever the original did this.
IdentityHashMap