From 74f134c83739778a7dd180808e6bfc9227009957 Mon Sep 17 00:00:00 2001 From: Eirik Bakke Date: Mon, 9 Aug 2021 01:02:59 +0200 Subject: [PATCH] [NETBEANS-5927] Have the Windows LAF default font follow actual platform settings. This effectively switches the GUI font from Tahoma 11 to Segoe UI 12. Fetch the default font for Windows applications using the same technique as as used by FlatLAF on Windows. --- .../plaf/windows8/Windows8LFCustoms.java | 119 ++++++++++-------- .../plaf/WinFlatEditorTabCellRenderer.java | 2 +- 2 files changed, 70 insertions(+), 51 deletions(-) diff --git a/platform/o.n.swing.plaf/src/org/netbeans/swing/plaf/windows8/Windows8LFCustoms.java b/platform/o.n.swing.plaf/src/org/netbeans/swing/plaf/windows8/Windows8LFCustoms.java index 8afb4a0184bf..118ae8553109 100644 --- a/platform/o.n.swing.plaf/src/org/netbeans/swing/plaf/windows8/Windows8LFCustoms.java +++ b/platform/o.n.swing.plaf/src/org/netbeans/swing/plaf/windows8/Windows8LFCustoms.java @@ -23,9 +23,9 @@ import java.awt.Font; import java.awt.Image; import java.awt.Insets; +import java.awt.Toolkit; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -34,6 +34,8 @@ import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.FontUIResource; +import javax.swing.text.StyleContext; import org.netbeans.swing.plaf.LFCustoms; import org.netbeans.swing.plaf.util.UIBootstrapValue; import org.netbeans.swing.plaf.util.UIUtils; @@ -65,36 +67,62 @@ public final class Windows8LFCustoms extends LFCustoms { // There is also a SCROLLPANE_BORDER_COLOR constant in the superclass. Both seem to be in use. static final String SCROLLPANE_BORDER_COLOR2 = "scrollpane_border"; //NOI18N + /** + * A list of {@link UIDefaults} font properties which may need adjustment of the font family + * and/or font size. + */ private static final String[] DEFAULT_GUI_FONT_PROPERTIES = new String[] { + /* These font properties are usually set to Tahoma 11 by Swing's Windows LAF. Since + Windows Vista, the default Windows font has switched to Segoe UI 12. Swing kept Tahoma 11 + for backwards compatibility reasons only; see https://www.pushing-pixels.org/page/213?m and + JDK-6669448. + + There's also a JDK Swing LAF bug which causes these font properties to be assigned the wrong + size under certain HiDPI configurations. Currently, JDK's WindowsLookAndFeel derives font + properties such as Label.font from the Windows API call GetStockObject(DEFAULT_GUI_FONT), + which appears to be unreliable when HiDPI display configurations are changed without logging + out of Windows and back in again (as may frequently happen, for instance, when an external + monitor is connected or disconnected). See the "win.defaultGUI.font" property in + WindowsLookAndFeel and + java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp . The + "win.messagebox.font" property is not affected by this problem, however, so we fetch the + default font using that one instead. FlatLAF does the same, in + com.formdev.flatlaf.FlatLaf.initialize(). Note that the font size in the + "win.defaultGUI.font" property may still be affected by the "Make text bigger" option in the + Windows 10 control panel, which exists independently of monitor-level HiDPI scaling + settings. */ "TitledBorder.font", "Slider.font", "PasswordField.font", "TableHeader.font", "TextPane.font", "ProgressBar.font", "Viewport.font", "TabbedPane.font", "List.font", "CheckBox.font", "Table.font", "ScrollPane.font", "ToggleButton.font", "Panel.font", "RadioButton.font", "FormattedTextField.font", "TextField.font", "Spinner.font", "Button.font", "EditorPane.font", - "Label.font", "ComboBox.font", "Tree.font", "TextArea.font" }; //NOI18N + "Label.font", "ComboBox.font", "Tree.font", + /* This one is Monospaced 13 by default, but should be switched to the standard UI font. + (This particular font substitution has been part of NetBeans since at least 2004.) */ + "TextArea.font", + /* These font properties seem to be unaffected by the aforementioned HiDPI bug, and are also + set to Segoe UI 12 by Swing's Windows LAF. But include them in the list of fonts to update, + for consistency in case of future changes. */ + "CheckBoxMenuItem.font", "OptionPane.font", "Menu.font", "ToolTip.font", "PopupMenu.font", + "RadioButtonMenuItem.font", "MenuItem.font", "ToolBar.font", "MenuBar.font", + /* This one is usually set to "Dialog 12" by default. Include it in the list to switch it to + Segoe UI as well. */ + "ColorChooser.font" + }; //NOI18N + + // Copied from com.formdev.flatlaf.FlatLAF.createCompositeFont. + private static FontUIResource createCompositeFont(String family, int style, int size) { + // using StyleContext.getFont() here because it uses + // sun.font.FontUtilities.getCompositeFontUIResource() + // and creates a composite font that is able to display all Unicode characters + Font font = StyleContext.getDefaultStyleContext().getFont(family, style, size); + return (font instanceof FontUIResource) ? (FontUIResource) font : new FontUIResource(font); + } final Color TAB_CONTENT_BORDER_COLOR = new Color(156, 156, 156); @Override public Object[] createLookAndFeelCustomizationKeysAndValues() { - /* Don't try to fetch this font size from the LAF; it won't work reliably for HiDPI - configurations (see a related workaround below). */ - int fontsize = 11; - Integer in = (Integer) UIManager.get(CUSTOM_FONT_SIZE); //NOI18N - if (in != null) { - fontsize = in.intValue(); - } - //Work around a bug in windows which sets the text area font to - //"MonoSpaced", causing all accessible dialogs to have monospaced text - Font textAreaFont = UIManager.getFont("Label.font"); //NOI18N - if (textAreaFont == null) { - textAreaFont = new Font("Dialog", Font.PLAIN, fontsize); //NOI18N - } else { - textAreaFont = textAreaFont.deriveFont((float) fontsize); - } - Object[] constants = new Object[] { - "TextArea.font", textAreaFont, //NOI18N - EDITOR_PREFERRED_COLOR_PROFILE, "NetBeans", //NOI18N EDITOR_ERRORSTRIPE_SCROLLBAR_INSETS, new Insets(17, 0, 17, 0), @@ -128,36 +156,27 @@ apps. Fixing that would be a bigger job, though (replacing WindowsPopupMenuSepar List result = new ArrayList<>(); result.addAll(Arrays.asList(constants)); - /* Workaround for Windows LAF JDK bug that causes fonts to appear at the wrong size on - certain configurations involving HiDPI monitors. Currently, WindowsLookAndFeel derive - font properties such as Label.font from the Windows API call - GetStockObject(DEFAULT_GUI_FONT), which appears to be unreliable when HiDPI display - configurations are changed without logging out of Windows and back in again (as may - frequently happen, for instance, when an external monitor is connected or - disconnected). See the "win.defaultGUI.font" property in WindowsLookAndFeel and - java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp . */ - /* If a custom font size is set, the font sizes have already been set in - AllLFCustoms.initCustomFontSize. */ - if (UIManager.get(CUSTOM_FONT_SIZE) == null) { - /* Use the same logic as in AllLFCustoms.switchFont, since it seems to take some special - precautions (e.g. using deriveFont instead of FontUIResource for the Windows case). */ - Map fontTranslation = new HashMap<>(); + // Adjust fonts; see comments on DEFAULT_GUI_FONT_PROPERTIES. + { + // Fallback values. + int fontSize = 11; + String fontFamily = "Dialog"; + Object messageBoxFont = + Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); + if (messageBoxFont instanceof Font) { + fontSize = ((Font) messageBoxFont).getSize(); + fontFamily = ((Font) messageBoxFont).getFamily(); + } + Object customFontSize = UIManager.get(CUSTOM_FONT_SIZE); //NOI18N + if (customFontSize instanceof Integer) { + /* In this case, AllLFCustoms.switchFont will already have run, but we probably need + to change the font family, too, so still add the customizations here. */ + fontSize = (Integer) customFontSize; + } + Font useFont = createCompositeFont(fontFamily, Font.PLAIN, fontSize); for (String uiKey : DEFAULT_GUI_FONT_PROPERTIES) { - if (uiKey.equals("TextArea.font")) { //NOI18N - // Skip this one; it was set earlier as part of an unrelated workaround. - continue; - } - Font oldFont = UIManager.getFont(uiKey); - if (oldFont == null) { - continue; - } - Font newFont = fontTranslation.get(oldFont); - if (newFont == null) { - newFont = oldFont.deriveFont((float) fontsize); - fontTranslation.put(oldFont, newFont); - } result.add(uiKey); - result.add(newFont); + result.add(useFont); } } @@ -380,14 +399,14 @@ TAB_BORDER_INNER, new Color(255,255,255), "ViewTab.unscaledBorders", true, // Left means left of the icon. Right means right of the caption, not of the "X" icon. - "EditorTab.tabInsets", new Insets(3,6,5,6), + "EditorTab.tabInsets", new Insets(3,6,3,6), "EditorTab.underlineHeight", 2, "EditorTab.underlineAtTop", true, "EditorTab.showTabSeparators", true, /* Left/top means left/top of the caption. Right means right of the caption. The X is centered vertically. */ - "ViewTab.tabInsets", new Insets(4,7,4,3), + "ViewTab.tabInsets", new Insets(2,7,4,3), "ViewTab.underlineHeight", 2, "ViewTab.underlineAtTop", true, "ViewTab.showTabSeparators", false, diff --git a/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/WinFlatEditorTabCellRenderer.java b/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/WinFlatEditorTabCellRenderer.java index 678d3840a969..64340416cd4d 100644 --- a/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/WinFlatEditorTabCellRenderer.java +++ b/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/WinFlatEditorTabCellRenderer.java @@ -116,7 +116,7 @@ protected int getCaptionYAdjustment() { Insets ins = getInsets(); int availH = getHeight() - (ins.top + ins.bottom); // Ad hoc adjustment for the Windows LAF. - int yAdjustment = 1; + int yAdjustment = -1; return ((availH <= txtH) ? -fm.getDescent() : -1) + yAdjustment; }