|
23 | 23 | import java.awt.Font; |
24 | 24 | import java.awt.Image; |
25 | 25 | import java.awt.Insets; |
| 26 | +import java.awt.Toolkit; |
26 | 27 | import java.util.ArrayList; |
27 | 28 | import java.util.Arrays; |
28 | | -import java.util.HashMap; |
29 | 29 | import java.util.List; |
30 | 30 | import java.util.Locale; |
31 | 31 | import java.util.Map; |
|
34 | 34 | import javax.swing.border.EmptyBorder; |
35 | 35 | import javax.swing.border.MatteBorder; |
36 | 36 | import javax.swing.plaf.ColorUIResource; |
| 37 | +import javax.swing.plaf.FontUIResource; |
| 38 | +import javax.swing.text.StyleContext; |
37 | 39 | import org.netbeans.swing.plaf.LFCustoms; |
38 | 40 | import org.netbeans.swing.plaf.util.UIBootstrapValue; |
39 | 41 | import org.netbeans.swing.plaf.util.UIUtils; |
@@ -65,36 +67,62 @@ public final class Windows8LFCustoms extends LFCustoms { |
65 | 67 | // There is also a SCROLLPANE_BORDER_COLOR constant in the superclass. Both seem to be in use. |
66 | 68 | static final String SCROLLPANE_BORDER_COLOR2 = "scrollpane_border"; //NOI18N |
67 | 69 |
|
| 70 | + /** |
| 71 | + * A list of {@link UIDefaults} font properties which may need adjustment of the font family |
| 72 | + * and/or font size. |
| 73 | + */ |
68 | 74 | private static final String[] DEFAULT_GUI_FONT_PROPERTIES = new String[] { |
| 75 | + /* These font properties are usually set to Tahoma 11 by Swing's Windows LAF. Since |
| 76 | + Windows Vista, the default Windows font has switched to Segoe UI 12. Swing kept Tahoma 11 |
| 77 | + for backwards compatibility reasons only; see https://www.pushing-pixels.org/page/213?m and |
| 78 | + JDK-6669448. |
| 79 | +
|
| 80 | + There's also a JDK Swing LAF bug which causes these font properties to be assigned the wrong |
| 81 | + size under certain HiDPI configurations. Currently, JDK's WindowsLookAndFeel derives font |
| 82 | + properties such as Label.font from the Windows API call GetStockObject(DEFAULT_GUI_FONT), |
| 83 | + which appears to be unreliable when HiDPI display configurations are changed without logging |
| 84 | + out of Windows and back in again (as may frequently happen, for instance, when an external |
| 85 | + monitor is connected or disconnected). See the "win.defaultGUI.font" property in |
| 86 | + WindowsLookAndFeel and |
| 87 | + java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp . The |
| 88 | + "win.messagebox.font" property is not affected by this problem, however, so we fetch the |
| 89 | + default font using that one instead. FlatLAF does the same, in |
| 90 | + com.formdev.flatlaf.FlatLaf.initialize(). Note that the font size in the |
| 91 | + "win.defaultGUI.font" property may still be affected by the "Make text bigger" option in the |
| 92 | + Windows 10 control panel, which exists independently of monitor-level HiDPI scaling |
| 93 | + settings. */ |
69 | 94 | "TitledBorder.font", "Slider.font", "PasswordField.font", "TableHeader.font", "TextPane.font", |
70 | 95 | "ProgressBar.font", "Viewport.font", "TabbedPane.font", "List.font", "CheckBox.font", |
71 | 96 | "Table.font", "ScrollPane.font", "ToggleButton.font", "Panel.font", "RadioButton.font", |
72 | 97 | "FormattedTextField.font", "TextField.font", "Spinner.font", "Button.font", "EditorPane.font", |
73 | | - "Label.font", "ComboBox.font", "Tree.font", "TextArea.font" }; //NOI18N |
| 98 | + "Label.font", "ComboBox.font", "Tree.font", |
| 99 | + /* This one is Monospaced 13 by default, but should be switched to the standard UI font. |
| 100 | + (This particular font substitution has been part of NetBeans since at least 2004.) */ |
| 101 | + "TextArea.font", |
| 102 | + /* These font properties seem to be unaffected by the aforementioned HiDPI bug, and are also |
| 103 | + set to Segoe UI 12 by Swing's Windows LAF. But include them in the list of fonts to update, |
| 104 | + for consistency in case of future changes. */ |
| 105 | + "CheckBoxMenuItem.font", "OptionPane.font", "Menu.font", "ToolTip.font", "PopupMenu.font", |
| 106 | + "RadioButtonMenuItem.font", "MenuItem.font", "ToolBar.font", "MenuBar.font", |
| 107 | + /* This one is usually set to "Dialog 12" by default. Include it in the list to switch it to |
| 108 | + Segoe UI as well. */ |
| 109 | + "ColorChooser.font" |
| 110 | + }; //NOI18N |
| 111 | + |
| 112 | + // Copied from com.formdev.flatlaf.FlatLAF.createCompositeFont. |
| 113 | + private static FontUIResource createCompositeFont(String family, int style, int size) { |
| 114 | + // using StyleContext.getFont() here because it uses |
| 115 | + // sun.font.FontUtilities.getCompositeFontUIResource() |
| 116 | + // and creates a composite font that is able to display all Unicode characters |
| 117 | + Font font = StyleContext.getDefaultStyleContext().getFont(family, style, size); |
| 118 | + return (font instanceof FontUIResource) ? (FontUIResource) font : new FontUIResource(font); |
| 119 | + } |
74 | 120 |
|
75 | 121 | final Color TAB_CONTENT_BORDER_COLOR = new Color(156, 156, 156); |
76 | 122 |
|
77 | 123 | @Override |
78 | 124 | public Object[] createLookAndFeelCustomizationKeysAndValues() { |
79 | | - /* Don't try to fetch this font size from the LAF; it won't work reliably for HiDPI |
80 | | - configurations (see a related workaround below). */ |
81 | | - int fontsize = 11; |
82 | | - Integer in = (Integer) UIManager.get(CUSTOM_FONT_SIZE); //NOI18N |
83 | | - if (in != null) { |
84 | | - fontsize = in.intValue(); |
85 | | - } |
86 | | - //Work around a bug in windows which sets the text area font to |
87 | | - //"MonoSpaced", causing all accessible dialogs to have monospaced text |
88 | | - Font textAreaFont = UIManager.getFont("Label.font"); //NOI18N |
89 | | - if (textAreaFont == null) { |
90 | | - textAreaFont = new Font("Dialog", Font.PLAIN, fontsize); //NOI18N |
91 | | - } else { |
92 | | - textAreaFont = textAreaFont.deriveFont((float) fontsize); |
93 | | - } |
94 | | - |
95 | 125 | Object[] constants = new Object[] { |
96 | | - "TextArea.font", textAreaFont, //NOI18N |
97 | | - |
98 | 126 | EDITOR_PREFERRED_COLOR_PROFILE, "NetBeans", //NOI18N |
99 | 127 | EDITOR_ERRORSTRIPE_SCROLLBAR_INSETS, new Insets(17, 0, 17, 0), |
100 | 128 |
|
@@ -128,36 +156,27 @@ apps. Fixing that would be a bigger job, though (replacing WindowsPopupMenuSepar |
128 | 156 | List<Object> result = new ArrayList<>(); |
129 | 157 | result.addAll(Arrays.asList(constants)); |
130 | 158 |
|
131 | | - /* Workaround for Windows LAF JDK bug that causes fonts to appear at the wrong size on |
132 | | - certain configurations involving HiDPI monitors. Currently, WindowsLookAndFeel derive |
133 | | - font properties such as Label.font from the Windows API call |
134 | | - GetStockObject(DEFAULT_GUI_FONT), which appears to be unreliable when HiDPI display |
135 | | - configurations are changed without logging out of Windows and back in again (as may |
136 | | - frequently happen, for instance, when an external monitor is connected or |
137 | | - disconnected). See the "win.defaultGUI.font" property in WindowsLookAndFeel and |
138 | | - java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp . */ |
139 | | - /* If a custom font size is set, the font sizes have already been set in |
140 | | - AllLFCustoms.initCustomFontSize. */ |
141 | | - if (UIManager.get(CUSTOM_FONT_SIZE) == null) { |
142 | | - /* Use the same logic as in AllLFCustoms.switchFont, since it seems to take some special |
143 | | - precautions (e.g. using deriveFont instead of FontUIResource for the Windows case). */ |
144 | | - Map<Font,Font> fontTranslation = new HashMap<>(); |
| 159 | + // Adjust fonts; see comments on DEFAULT_GUI_FONT_PROPERTIES. |
| 160 | + { |
| 161 | + // Fallback values. |
| 162 | + int fontSize = 11; |
| 163 | + String fontFamily = "Dialog"; |
| 164 | + Object messageBoxFont = |
| 165 | + Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); |
| 166 | + if (messageBoxFont instanceof Font) { |
| 167 | + fontSize = ((Font) messageBoxFont).getSize(); |
| 168 | + fontFamily = ((Font) messageBoxFont).getFamily(); |
| 169 | + } |
| 170 | + Object customFontSize = UIManager.get(CUSTOM_FONT_SIZE); //NOI18N |
| 171 | + if (customFontSize instanceof Integer) { |
| 172 | + /* In this case, AllLFCustoms.switchFont will already have run, but we probably need |
| 173 | + to change the font family, too, so still add the customizations here. */ |
| 174 | + fontSize = (Integer) customFontSize; |
| 175 | + } |
| 176 | + Font useFont = createCompositeFont(fontFamily, Font.PLAIN, fontSize); |
145 | 177 | for (String uiKey : DEFAULT_GUI_FONT_PROPERTIES) { |
146 | | - if (uiKey.equals("TextArea.font")) { //NOI18N |
147 | | - // Skip this one; it was set earlier as part of an unrelated workaround. |
148 | | - continue; |
149 | | - } |
150 | | - Font oldFont = UIManager.getFont(uiKey); |
151 | | - if (oldFont == null) { |
152 | | - continue; |
153 | | - } |
154 | | - Font newFont = fontTranslation.get(oldFont); |
155 | | - if (newFont == null) { |
156 | | - newFont = oldFont.deriveFont((float) fontsize); |
157 | | - fontTranslation.put(oldFont, newFont); |
158 | | - } |
159 | 178 | result.add(uiKey); |
160 | | - result.add(newFont); |
| 179 | + result.add(useFont); |
161 | 180 | } |
162 | 181 | } |
163 | 182 |
|
@@ -380,14 +399,14 @@ TAB_BORDER_INNER, new Color(255,255,255), |
380 | 399 | "ViewTab.unscaledBorders", true, |
381 | 400 |
|
382 | 401 | // Left means left of the icon. Right means right of the caption, not of the "X" icon. |
383 | | - "EditorTab.tabInsets", new Insets(3,6,5,6), |
| 402 | + "EditorTab.tabInsets", new Insets(3,6,3,6), |
384 | 403 | "EditorTab.underlineHeight", 2, |
385 | 404 | "EditorTab.underlineAtTop", true, |
386 | 405 | "EditorTab.showTabSeparators", true, |
387 | 406 |
|
388 | 407 | /* Left/top means left/top of the caption. Right means right of the caption. The X is |
389 | 408 | centered vertically. */ |
390 | | - "ViewTab.tabInsets", new Insets(4,7,4,3), |
| 409 | + "ViewTab.tabInsets", new Insets(2,7,4,3), |
391 | 410 | "ViewTab.underlineHeight", 2, |
392 | 411 | "ViewTab.underlineAtTop", true, |
393 | 412 | "ViewTab.showTabSeparators", false, |
|
0 commit comments