Fehler oder Feature: Swing-Standard-GUI-Schriftart für Win6 + falsch
Nur (erstaunlicherweise ;-) ist aufgefallen, warum Apps auf meinen win6 + -Maschinen so beengt aussehen (gleiches gilt für Vista und Win7, beide mit 120 dpi Einstellung, jdk6 und jdk7): Die Kontrollschrift, die in der Desktop-Eigenschaft nachgeschlagen wurde, hat beide die falsche Schrift Familie und die falsche Größe:
public static void main(String[] args) {
Font guiFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty("win.defaultGUI.font");
int guiSize = guiFont.getSize();
Font iconFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty("win.icon.font");
System.out.println("gui default: " + guiFont + "\nicon default: " + iconFont);
}
Ausgabe:
gui default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=13]
icon default: java.awt.Font[family=Segoe UI,name=Segoe UI,style=plain,size=15]
Letzteres wird in nativen Anwendungen für fast den gesamten Text verwendet, während Swing das erstere verwendet ...
Fragen:
Könnte es einen Grund dafür geben oder nur einen Fehler?Wer ist dafür verantwortlich, dass die Swing-Suche (beim Einlesen der desktopProperty von relevanten Systemressourcen) oder das Betriebssystem sie nicht korrekt meldet?Wie kann man die Verwendung des letzteren erzwingen?Optionen zum Lösen der letzten:
Bei vollständiger Kontrolle über das LAF kann es in Betracht gezogen werden, alle relevanten Textschriftarten festzulegen (dies ist die Aufgabe von JGoodies, die in einem FontPolicy / Set berücksichtigt wird).Ein schmutziger Hack besteht darin, den Wert der defaultGUI-Desktopeigenschaft auf den richtigen Wert zu setzen - dies beinhaltet einen reflektierten Zugriff auf das Toolkit, was natürlich sicherheitsbedingte Kontexte zunichte macht.??Bearbeiten
Nur für den Fall, dass jemand interessiert ist, hier ist der schmutzige Hack:
/**
* Replaces the default gui desktop font property with the icon font
* if the former is smaller.
*
*/
public static void ensureDefaultGUIFontSize() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Font guiFont = (Font) toolkit.getDesktopProperty("win.defaultGUI.font");
Font iconFont = (Font) toolkit.getDesktopProperty("win.icon.font");
if (guiFont.getSize() < iconFont.getSize()) {
invokeDeclaredMethod("setDesktopProperty", Toolkit.class,
toolkit, "win.defaultGUI.font", iconFont);
}
}
private static void invokeDeclaredMethod(String methodName,
Class<?> clazz, Object instance, String propertyName,
Object propertyValue) {
try {
Method method = clazz.getDeclaredMethod(methodName, String.class, Object.class);
method.setAccessible(true);
method.invoke(instance, propertyName, propertyValue);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
LOG.finer("forcing desktop property failed " + e.getStackTrace());
}
}
Bearbeiten 2
Nur zur Verdeutlichung: Der Hack ist nur für WindowsLAF vollständig wirksam. Nimbus ignoriert die Systemeinstellungen vollständig, Metal teilweise: Die Schriftart des letzteren ist immer Dialog, nur die Größe wird von desktopProperties übernommen. Klingt halbwegs gut, ist es aber nicht: Die Zuordnung ist für die Hauptschriftarten, z. Die häufig verwendete controlFont-Größe lautet "win.ansiVar.font.height" (was ist das für ein fossiles Überbleibsel?) und ist 13 auf meinem Computer ...
Bearbeiten 3
Sogar in Windows UI ist der Hack ... ein Hack mit Einschränkungen, f.i. die in @ Walters Kommentar erwähnten:
Dieser Fehler macht sich insbesondere beim Skalieren der Windows-Benutzeroberfläche bemerkbar. Wenn Sie einen JFileChooser öffnen, wird der Hack rückgängig gemacht. Auch die Zeilenhöhe von JTree / JTable wird nicht automatisch auf die neue Schriftgröße aktualisiert, und Sie müssen auch Ihre Symbole skalieren