1 | /******************************************************************************* | |
2 | * Copyhacked (H) 2012-2020. | |
3 | * This program and the accompanying materials | |
4 | * are made available under no term at all, use it like | |
5 | * you want, but share and discuss about it | |
6 | * every time possible with every body. | |
7 | * | |
8 | * Contributors: | |
9 | * ron190 at ymail dot com - initial implementation | |
10 | ******************************************************************************/ | |
11 | package com.jsql.view.swing.util; | |
12 | ||
13 | import com.jsql.util.LogLevelUtil; | |
14 | import com.jsql.view.swing.sql.lexer.HighlightedDocument; | |
15 | import com.jsql.view.swing.text.action.DeleteNextCharAction; | |
16 | import com.jsql.view.swing.text.action.DeletePrevCharAction; | |
17 | import com.jsql.view.swing.ui.BorderRoundBlu; | |
18 | import com.jsql.view.swing.ui.CheckBoxIcon; | |
19 | import com.jsql.view.swing.ui.CustomBasicComboBoxUI; | |
20 | import org.apache.commons.lang3.SystemUtils; | |
21 | import org.apache.logging.log4j.LogManager; | |
22 | import org.apache.logging.log4j.Logger; | |
23 | ||
24 | import javax.imageio.ImageIO; | |
25 | import javax.swing.*; | |
26 | import javax.swing.border.AbstractBorder; | |
27 | import javax.swing.border.Border; | |
28 | import javax.swing.border.LineBorder; | |
29 | import javax.swing.plaf.ColorUIResource; | |
30 | import javax.swing.text.DefaultCaret; | |
31 | import javax.swing.text.DefaultEditorKit; | |
32 | import javax.swing.text.JTextComponent; | |
33 | import java.awt.*; | |
34 | import java.awt.event.FocusEvent; | |
35 | import java.awt.event.FocusListener; | |
36 | import java.awt.image.BufferedImage; | |
37 | import java.io.BufferedInputStream; | |
38 | import java.io.IOException; | |
39 | import java.io.InputStream; | |
40 | import java.net.URL; | |
41 | import java.util.ArrayList; | |
42 | import java.util.List; | |
43 | import java.util.Objects; | |
44 | ||
45 | /** | |
46 | * Build default component appearance, keyboard shortcuts and icons. | |
47 | */ | |
48 | public class UiUtil { | |
49 | | |
50 | /** | |
51 | * Log4j logger sent to view. | |
52 | */ | |
53 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
54 | ||
55 | public static final Color COLOR_BLU = new Color(132, 172, 221); | |
56 | public static final Color COLOR_GREEN = new Color(0, 128, 0); | |
57 | public static final String TEXTPANE_FONT = "TextPane.font"; | |
58 | ||
59 | // Color TabbedPane.selected hardcoded for Mac value is missing | |
60 | public static final Color COLOR_FOCUS_GAINED = new Color(200, 221, 242); | |
61 | | |
62 | public static final Color COLOR_DEFAULT_BACKGROUND = UIManager.getColor("Panel.background"); | |
63 | public static final Color COLOR_COMPONENT_BORDER = UIManager.getColor("controlShadow"); | |
64 | public static final Color COLOR_FOCUS_LOST = new Color(248, 249, 249); | |
65 | public static final Border BORDER_FOCUS_LOST = new LineBorder(new Color(218, 218, 218), 1, false); | |
66 | public static final Border BORDER_FOCUS_GAINED = new LineBorder(UiUtil.COLOR_COMPONENT_BORDER, 1, false); | |
67 | | |
68 | public static final URL URL_GLOBE = UiUtil.class.getClassLoader().getResource("swing/images/icons/globe.png"); | |
69 | | |
70 | public static final Icon ICON_TICK = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/check.png"))); | |
71 | public static final Icon ICON_SQUARE_RED = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/squareRed.png"))); | |
72 | public static final Icon ICON_SQUARE_GREY = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/squareGrey.png"))); | |
73 | public static final Icon ICON_LOADER_GIF = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/spinner.gif"))); | |
74 | ||
75 | public static final Icon ICON_ADMIN_SERVER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/admin.png"))); | |
76 | public static final Icon ICON_SHELL_SERVER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/application_xp_terminal.png"))); | |
77 | public static final Icon ICON_DATABASE_SERVER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/database.png"))); | |
78 | public static final Icon ICON_FILE_SERVER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/file.png"))); | |
79 | public static final Icon ICON_COG = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/cog.png"))); | |
80 | public static final Icon ICON_BRUTER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/lock_open.png"))); | |
81 | public static final Icon ICON_CODER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/textfield.png"))); | |
82 | public static final Icon ICON_UPLOAD = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/disk.png"))); | |
83 | public static final Icon ICON_SCANLIST = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/table_multiple.png"))); | |
84 | ||
85 | public static final Icon ICON_TABLE = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/table.png"))); | |
86 | public static final Icon ICON_TABLE_GO = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/tableGo.png"))); | |
87 | public static final Icon ICON_DATABASE = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/database.png"))); | |
88 | public static final Icon ICON_DATABASE_GO = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/databaseGo.png"))); | |
89 | | |
90 | public static final Icon ICON_CONSOLE = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/console.gif"))); | |
91 | public static final Icon ICON_HEADER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/header.gif"))); | |
92 | public static final Icon ICON_CHUNK = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/chunk.gif"))); | |
93 | public static final Icon ICON_BINARY = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/binary.gif"))); | |
94 | public static final Icon ICON_CUP = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/cup.png"))); | |
95 | | |
96 | public static final Icon ICON_CLOSE = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/close.png"))); | |
97 | public static final Icon ICON_CLOSE_ROLLOVER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/closeRollover.png"))); | |
98 | public static final Icon ICON_CLOSE_PRESSED = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/closePressed.png"))); | |
99 | ||
100 | public static final Icon ICON_ARROW_DEFAULT = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/arrowDefault.png"))); | |
101 | public static final Icon ICON_ARROW_ROLLOVER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/arrowRollover.png"))); | |
102 | public static final Icon ICON_ARROW_PRESSED = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/arrowPressed.png"))); | |
103 | ||
104 | public static final Icon ICON_EXPAND_TEXT = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/expand.png"))); | |
105 | ||
106 | public static final Icon ICON_FLAG_AR = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/ar.png"))); | |
107 | public static final Icon ICON_FLAG_ZH = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/zh.png"))); | |
108 | public static final Icon ICON_FLAG_RU = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/ru.png"))); | |
109 | public static final Icon ICON_FLAG_TR = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/tr.png"))); | |
110 | public static final Icon ICON_FLAG_EN = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/en.png"))); | |
111 | public static final Icon ICON_FLAG_FR = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/fr.png"))); | |
112 | public static final Icon ICON_FLAG_HI = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/hi.png"))); | |
113 | public static final Icon ICON_FLAG_CS = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/cs.png"))); | |
114 | public static final Icon ICON_FLAG_DE = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/de.png"))); | |
115 | public static final Icon ICON_FLAG_NL = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/nl.png"))); | |
116 | public static final Icon ICON_FLAG_IN_ID = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/id.png"))); | |
117 | public static final Icon ICON_FLAG_IT = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/it.png"))); | |
118 | public static final Icon ICON_FLAG_ES = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/es.png"))); | |
119 | public static final Icon ICON_FLAG_PT = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/pt.png"))); | |
120 | public static final Icon ICON_FLAG_PL = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/pl.png"))); | |
121 | public static final Icon ICON_FLAG_JA = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/ja.png"))); | |
122 | public static final Icon ICON_FLAG_KO = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/ko.png"))); | |
123 | public static final Icon ICON_FLAG_RO = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/ro.png"))); | |
124 | public static final Icon ICON_FLAG_LK = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/lk.png"))); | |
125 | public static final Icon ICON_FLAG_SE = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/se.png"))); | |
126 | public static final Icon ICON_FLAG_FI = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/flags/fi.png"))); | |
127 | | |
128 | public static final URL URL_ICON_16 = UiUtil.class.getClassLoader().getResource("swing/images/software/bug16.png"); | |
129 | public static final URL URL_ICON_32 = UiUtil.class.getClassLoader().getResource("swing/images/software/bug32.png"); | |
130 | public static final URL URL_ICON_96 = UiUtil.class.getClassLoader().getResource("swing/images/software/bug96.png"); | |
131 | public static final URL URL_ICON_128 = UiUtil.class.getClassLoader().getResource("swing/images/software/bug128.png"); | |
132 | ||
133 | // The drop shadow is created from a PNG image with 8 bit alpha channel. | |
134 | public static final Image IMG_SHADOW = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/shadow.png"))).getImage(); | |
135 | | |
136 | public static final ImageIcon IMG_BUG = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/bug.png"))); | |
137 | public static final ImageIcon IMG_STOP_DEFAULT = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/stopDefault.png"))); | |
138 | public static final ImageIcon IMG_STOP_ROLLOVER = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/stopRollover.png"))); | |
139 | public static final ImageIcon IMG_STOP_PPRESSED = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/stopPressed.png"))); | |
140 | | |
141 | public static final String PATH_WEB_FOLDERS = "swing/list/payload.txt"; | |
142 | public static final String INPUT_STREAM_PAGES_SCAN = "swing/list/scan-page.json"; | |
143 | ||
144 | // Set a margin on menu item on non Mac OS | |
145 | public static final Icon ICON_EMPTY = new ImageIcon(new BufferedImage(16, 16, Transparency.TRANSLUCENT)); | |
146 | ||
147 | public static final String PATH_PAUSE = "swing/images/icons/pause.png"; | |
148 | public static final String PATH_PROGRESSBAR = "swing/images/icons/progressBar.gif"; | |
149 | | |
150 | public static final Icon ICON_ERROR = new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/error.png"))); | |
151 | | |
152 | public static final Border BORDER_BLU = BorderFactory.createCompoundBorder( | |
153 | BORDER_FOCUS_GAINED, | |
154 | BorderFactory.createEmptyBorder(2, 2, 2, 2) | |
155 | ); | |
156 | | |
157 | public static final Border BORDER_ROUND_BLU = new BorderRoundBlu(); | |
158 | ||
159 | public static final String FONT_NAME_MONO_NON_ASIAN = "Ubuntu Mono"; | |
160 | public static final int FONT_SIZE_MONO_NON_ASIAN = 14; | |
161 | public static final String FONT_NAME_MONO_ASIAN = "Monospace"; | |
162 | public static final int FONT_SIZE_MONO_ASIAN = 13; | |
163 | | |
164 | // Used in Translation Dialog | |
165 | // HTML engine considers Monospaced/Monospace to be the same Font | |
166 | // Java engine recognizes only Monospaced | |
167 | public static final String FONT_NAME_MONOSPACED = "Monospaced"; | |
168 | ||
169 | public static final Font FONT_MONO_NON_ASIAN = new Font( | |
170 | UiUtil.FONT_NAME_MONO_NON_ASIAN, | |
171 | Font.PLAIN, | |
172 | UIManager.getDefaults().getFont("TextArea.font").getSize() + 2 | |
173 | ); | |
174 | | |
175 | public static final Font FONT_MONO_ASIAN = new Font( | |
176 | UiUtil.FONT_NAME_MONO_ASIAN, | |
177 | Font.PLAIN, | |
178 | UIManager.getDefaults().getFont(TEXTPANE_FONT).getSize() | |
179 | ); | |
180 | | |
181 | public static final Font FONT_NON_MONO = new Font( | |
182 | "Segoe UI", | |
183 | Font.PLAIN, | |
184 | UIManager.getDefaults().getFont(TEXTPANE_FONT).getSize() | |
185 | ); | |
186 | | |
187 | public static final Font FONT_NON_MONO_BIG = new Font( | |
188 | UIManager.getDefaults().getFont("TextField.font").getName(), | |
189 | Font.PLAIN, | |
190 | UIManager.getDefaults().getFont("TextField.font").getSize() + 2 | |
191 | ); | |
192 | ||
193 | public static final String CHUNK_VISIBLE = "chunk_visible"; | |
194 | public static final String BINARY_VISIBLE = "binary_visible"; | |
195 | public static final String NETWORK_VISIBLE = "header_visible"; | |
196 | public static final String JAVA_VISIBLE = "java_visible"; | |
197 | | |
198 | private UiUtil() { | |
199 | // Utility class | |
200 | } | |
201 | | |
202 | /** | |
203 | * Change the default style of various components. | |
204 | */ | |
205 | public static void prepareGUI() { | |
206 | | |
207 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::loadFonts → NO_COVERAGE |
loadFonts(); |
208 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureToolTip → NO_COVERAGE |
configureToolTip(); |
209 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureButton → NO_COVERAGE |
configureButton(); |
210 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureMenu → NO_COVERAGE |
configureMenu(); |
211 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureTabbedPane → NO_COVERAGE |
configureTabbedPane(); |
212 | | |
213 | UIManager.put("FileChooser.listFont", UiUtil.FONT_NON_MONO); | |
214 | UIManager.put("FileChooser.listViewBorder", BorderFactory.createCompoundBorder( | |
215 | BorderFactory.createLineBorder(UiUtil.COLOR_BLU), | |
216 | BorderFactory.createMatteBorder(2,2,2,2, Color.WHITE) | |
217 | )); | |
218 | ||
219 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureText → NO_COVERAGE |
configureText(); |
220 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureTable → NO_COVERAGE |
configureTable(); |
221 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureTree → NO_COVERAGE |
configureTree(); |
222 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureProgressBar → NO_COVERAGE |
configureProgressBar(); |
223 |
1
1. prepareGUI : removed call to com/jsql/view/swing/util/UiUtil::configureComboBox → NO_COVERAGE |
configureComboBox(); |
224 | | |
225 | UIManager.put("swing.boldMetal", Boolean.FALSE); | |
226 | } | |
227 | ||
228 | private static void loadFonts() { | |
229 | | |
230 | var graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment(); | |
231 | | |
232 | try (InputStream fontStream = new BufferedInputStream(Objects.requireNonNull(UiUtil.class.getClassLoader().getResourceAsStream("swing/font/UbuntuMono-R-ctrlchar.ttf")))) { | |
233 | | |
234 | var ubuntuFont = Font.createFont(Font.TRUETYPE_FONT, fontStream); | |
235 | graphicsEnvironment.registerFont(ubuntuFont); | |
236 | | |
237 | } catch (FontFormatException | IOException e) { | |
238 | LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Loading Font Ubuntu Mono with control characters failed", e); | |
239 | } | |
240 | } | |
241 | ||
242 | private static void configureText() { | |
243 | | |
244 | // Custom text component | |
245 | // Admin page | |
246 | UIManager.put("TextPane.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
247 | UIManager.put(TEXTPANE_FONT, UiUtil.FONT_MONO_NON_ASIAN); | |
248 | UIManager.put("TextPane.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
249 | | |
250 | UIManager.put("TextField.border", UiUtil.BORDER_BLU); | |
251 | UIManager.put("TextField.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
252 | | |
253 | UIManager.put("EditorPane.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
254 | | |
255 | UIManager.put("TextArea.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
256 | UIManager.put("TextArea.font", UiUtil.FONT_MONO_NON_ASIAN); | |
257 | ||
258 | // Custom Label | |
259 | UIManager.put("Label.font", UiUtil.FONT_NON_MONO); | |
260 | UIManager.put("Label.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
261 | } | |
262 | ||
263 | private static void configureButton() { | |
264 | | |
265 | UIManager.put("Button.font", UiUtil.FONT_NON_MONO); | |
266 | UIManager.put("CheckBox.font", UiUtil.FONT_NON_MONO); | |
267 | UIManager.put("RadioButton.font", UiUtil.FONT_NON_MONO); | |
268 | UIManager.put("TitledBorder.font", UiUtil.FONT_NON_MONO); | |
269 | ||
270 | UIManager.put("Spinner.arrowButtonBorder", UiUtil.BORDER_BLU); | |
271 | UIManager.put("Spinner.border", BorderFactory.createLineBorder(UiUtil.COLOR_COMPONENT_BORDER, 1, false)); | |
272 | UIManager.put("Spinner.disableOnBoundaryValues", Boolean.TRUE); | |
273 | | |
274 | // Custom button | |
275 | // Change border of button in default Save as, Confirm dialogs | |
276 | UIManager.put("Button.border", UiUtil.BORDER_BLU); | |
277 | UIManager.put("Button.select", new Color(155, 193, 232)); | |
278 | | |
279 | // Change border of button in Save as dialog | |
280 | UIManager.put("ToggleButton.border", UiUtil.BORDER_BLU); | |
281 | | |
282 | UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE); | |
283 | } | |
284 | ||
285 | private static void configureToolTip() { | |
286 | | |
287 | // Custom tooltip | |
288 | // timer before showing tooltip | |
289 |
1
1. configureToolTip : removed call to javax/swing/ToolTipManager::setInitialDelay → NO_COVERAGE |
ToolTipManager.sharedInstance().setInitialDelay(750); |
290 | // timer before closing automatically tooltip | |
291 |
1
1. configureToolTip : removed call to javax/swing/ToolTipManager::setDismissDelay → NO_COVERAGE |
ToolTipManager.sharedInstance().setDismissDelay(30000); |
292 | // timer used when mouse move to another component, show tooltip immediately if timer is not expired | |
293 |
1
1. configureToolTip : removed call to javax/swing/ToolTipManager::setReshowDelay → NO_COVERAGE |
ToolTipManager.sharedInstance().setReshowDelay(1); |
294 | ||
295 | UIManager.put("ToolTip.background", new Color(255, 255, 225)); | |
296 | UIManager.put("ToolTip.backgroundInactive", new Color(255, 255, 225)); | |
297 | UIManager.put("ToolTip.foreground", Color.BLACK); | |
298 | UIManager.put("ToolTip.foregroundInactive", Color.BLACK); | |
299 | UIManager.put("ToolTip.font", UiUtil.FONT_NON_MONO); | |
300 | } | |
301 | ||
302 | private static void configureTabbedPane() { | |
303 | | |
304 | // Custom tab | |
305 | UIManager.put("TabbedPane.contentAreaColor", UiUtil.FONT_MONO_NON_ASIAN); | |
306 | UIManager.put("TabbedPane.font", UiUtil.FONT_NON_MONO); | |
307 | // margin of current tab panel | |
308 | UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0)); | |
309 | // margin above tabs | |
310 | UIManager.put("TabbedPane.tabAreaInsets", new Insets(3, 2, 0, 2)); | |
311 | // margin around tab name | |
312 | UIManager.put("TabbedPane.tabInsets", new Insets(2, 3 + 5, 2, 3)); | |
313 | // lighter unselected tab border | |
314 | UIManager.put("TabbedPane.darkShadow", new Color(190,198,205)); | |
315 | } | |
316 | ||
317 | private static void configureMenu() { | |
318 | | |
319 | // Prevent green glitch on Mac menu | |
320 |
1
1. configureMenu : negated conditional → NO_COVERAGE |
if (!SystemUtils.IS_OS_MAC) { |
321 | | |
322 | // No bold for menu + round corner | |
323 | UIManager.put("Menu.font", UiUtil.FONT_NON_MONO); | |
324 | UIManager.put("Menu.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
325 | UIManager.put("Menu.borderPainted", false); | |
326 | UIManager.put("PopupMenu.font", UiUtil.FONT_NON_MONO); | |
327 | UIManager.put("RadioButtonMenuItem.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
328 | UIManager.put("RadioButtonMenuItem.font", UiUtil.FONT_NON_MONO); | |
329 | UIManager.put("RadioButtonMenuItem.borderPainted", false); | |
330 | UIManager.put("MenuItem.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
331 | UIManager.put("MenuItem.font", UiUtil.FONT_NON_MONO); | |
332 | UIManager.put("MenuItem.borderPainted", false); | |
333 | UIManager.put("MenuItem.disabledAreNavigable", Boolean.TRUE); | |
334 | | |
335 | UIManager.put("CheckBoxMenuItem.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
336 | UIManager.put("CheckBoxMenuItem.font", UiUtil.FONT_NON_MONO); | |
337 | UIManager.put("CheckBoxMenuItem.borderPainted", false); | |
338 | UIManager.put("CheckBoxMenuItem.checkIcon", new CheckBoxIcon()); | |
339 | } | |
340 | } | |
341 | ||
342 | private static void configureTable() { | |
343 | | |
344 | // Custom table | |
345 | UIManager.put("Table.font", UiUtil.FONT_NON_MONO); | |
346 | UIManager.put("TableHeader.font", UiUtil.FONT_NON_MONO); | |
347 | UIManager.put("Table.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
348 | | |
349 | UIManager.put("Table.focusCellHighlightBorder", | |
350 | BorderFactory.createCompoundBorder( | |
351 | new AbstractBorder() { | |
352 | | |
353 | @Override | |
354 | public void paintBorder(Component comp, Graphics g, int x, int y, int w, int h) { | |
355 | | |
356 | Graphics2D g2D = (Graphics2D) g; | |
357 |
1
1. paintBorder : removed call to java/awt/Graphics2D::setColor → NO_COVERAGE |
g2D.setColor(Color.GRAY); |
358 |
1
1. paintBorder : removed call to java/awt/Graphics2D::setStroke → NO_COVERAGE |
g2D.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{1}, 0)); |
359 | | |
360 | // Fix #42291: InternalError on drawRect() | |
361 | try { | |
362 |
3
1. paintBorder : Replaced integer subtraction with addition → NO_COVERAGE 2. paintBorder : removed call to java/awt/Graphics2D::drawRect → NO_COVERAGE 3. paintBorder : Replaced integer subtraction with addition → NO_COVERAGE |
g2D.drawRect(x, y, w - 1, h - 1); |
363 | } catch (InternalError e) { | |
364 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e); | |
365 | } | |
366 | } | |
367 | }, | |
368 | BorderFactory.createEmptyBorder(0, 1, 0, 0) | |
369 | ) | |
370 | ); | |
371 | } | |
372 | ||
373 | private static void configureTree() { | |
374 | | |
375 | // Custom tree | |
376 | UIManager.put("Tree.expandedIcon", new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/expanded.png")))); | |
377 | UIManager.put("Tree.collapsedIcon", new ImageIcon(Objects.requireNonNull(UiUtil.class.getClassLoader().getResource("swing/images/icons/collapsed.png")))); | |
378 | UIManager.put("Tree.lineTypeDashed", true); | |
379 | | |
380 | // No default icon for tree nodes | |
381 | UIManager.put("Tree.leafIcon", new ImageIcon()); | |
382 | UIManager.put("Tree.openIcon", new ImageIcon()); | |
383 | UIManager.put("Tree.closedIcon", new ImageIcon()); | |
384 | } | |
385 | ||
386 | private static void configureComboBox() { | |
387 | | |
388 | // Custom ComboBox | |
389 | UIManager.put("ComboBox.font", UiUtil.FONT_NON_MONO); | |
390 | UIManager.put("ComboBox.selectionBackground", UiUtil.COLOR_FOCUS_GAINED); | |
391 | | |
392 | // Use ColorUIResource to preserve the background color for arrow | |
393 | UIManager.put("ComboBox.background", new ColorUIResource(Color.WHITE)); | |
394 | UIManager.put("ComboBox.border", UiUtil.BORDER_BLU); | |
395 | UIManager.put("ComboBoxUI", CustomBasicComboBoxUI.class.getName()); | |
396 | } | |
397 | ||
398 | private static void configureProgressBar() { | |
399 | | |
400 | // Custom progress bar | |
401 | UIManager.put("ProgressBar.border", BorderFactory.createCompoundBorder( | |
402 | BorderFactory.createEmptyBorder(3, 0, 4, 0), | |
403 | BorderFactory.createCompoundBorder( | |
404 | BorderFactory.createLineBorder(Color.GRAY), | |
405 | BorderFactory.createLineBorder(Color.WHITE) | |
406 | ) | |
407 | )); | |
408 | | |
409 | UIManager.put("ProgressBar.foreground", new Color(136, 183, 104)); | |
410 | UIManager.put("ProgressBar.background", UIManager.get("Tree.background")); | |
411 | } | |
412 | ||
413 | /** | |
414 | * Icons for application window. | |
415 | * @return List of a 16x16 (default) and 32x32 icon (alt-tab, taskbar) | |
416 | */ | |
417 | public static List<Image> getIcons() { | |
418 | | |
419 | List<Image> images = new ArrayList<>(); | |
420 | | |
421 | // Fix #2154: NoClassDefFoundError on read() | |
422 | try { | |
423 | images.add(ImageIO.read(Objects.requireNonNull(UiUtil.URL_ICON_128))); | |
424 | images.add(ImageIO.read(Objects.requireNonNull(UiUtil.URL_ICON_96))); | |
425 | images.add(ImageIO.read(Objects.requireNonNull(UiUtil.URL_ICON_32))); | |
426 | images.add(ImageIO.read(Objects.requireNonNull(UiUtil.URL_ICON_16))); | |
427 | | |
428 | } catch (NoClassDefFoundError | IOException e) { | |
429 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e); | |
430 | } | |
431 | | |
432 |
1
1. getIcons : replaced return value with Collections.emptyList for com/jsql/view/swing/util/UiUtil::getIcons → NO_COVERAGE |
return images; |
433 | } | |
434 | | |
435 | public static void drawPlaceholder(JTextComponent textComponent, Graphics g, String placeholderText) { | |
436 |
2
1. drawPlaceholder : Replaced integer addition with subtraction → NO_COVERAGE 2. drawPlaceholder : removed call to com/jsql/view/swing/util/UiUtil::drawPlaceholder → NO_COVERAGE |
drawPlaceholder(textComponent, g, placeholderText, g.getFontMetrics().getAscent() + 2); |
437 | } | |
438 | | |
439 | public static void drawPlaceholder(JTextComponent textComponent, Graphics g, String placeholderText, int y) { | |
440 | | |
441 | int w = textComponent.getWidth(); | |
442 | | |
443 |
1
1. drawPlaceholder : removed call to java/awt/Graphics2D::setRenderingHint → NO_COVERAGE |
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
444 | | |
445 | var ins = textComponent.getInsets(); | |
446 | var fm = g.getFontMetrics(); | |
447 | | |
448 | int c0 = textComponent.getBackground().getRGB(); | |
449 | int c1 = textComponent.getForeground().getRGB(); | |
450 | var m = 0xfefefefe; | |
451 |
5
1. drawPlaceholder : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE 2. drawPlaceholder : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE 3. drawPlaceholder : Replaced integer addition with subtraction → NO_COVERAGE 4. drawPlaceholder : Replaced bitwise AND with OR → NO_COVERAGE 5. drawPlaceholder : Replaced bitwise AND with OR → NO_COVERAGE |
int c2 = ((c0 & m) >>> 1) + ((c1 & m) >>> 1); |
452 | | |
453 |
1
1. drawPlaceholder : removed call to java/awt/Graphics::setColor → NO_COVERAGE |
g.setColor(new Color(c2, true)); |
454 |
1
1. drawPlaceholder : removed call to java/awt/Graphics::setFont → NO_COVERAGE |
g.setFont(textComponent.getFont().deriveFont(Font.ITALIC)); |
455 | ||
456 |
1
1. drawPlaceholder : removed call to java/awt/Graphics::drawString → NO_COVERAGE |
g.drawString( |
457 | placeholderText, | |
458 |
1
1. drawPlaceholder : negated conditional → NO_COVERAGE |
ComponentOrientation.RIGHT_TO_LEFT.equals(textComponent.getComponentOrientation()) |
459 |
3
1. drawPlaceholder : Replaced integer addition with subtraction → NO_COVERAGE 2. drawPlaceholder : Replaced integer subtraction with addition → NO_COVERAGE 3. drawPlaceholder : Replaced integer addition with subtraction → NO_COVERAGE |
? w - (fm.stringWidth(placeholderText) + ins.left + 2) |
460 |
1
1. drawPlaceholder : Replaced integer addition with subtraction → NO_COVERAGE |
: ins.left + 2, |
461 | y | |
462 | ); | |
463 | } | |
464 | | |
465 | public static void initialize(JTextComponent component) { | |
466 | ||
467 |
1
1. initialize : removed call to javax/swing/text/JTextComponent::setCaret → NO_COVERAGE |
component.setCaret(new DefaultCaret() { |
468 | | |
469 | @Override | |
470 | public void setSelectionVisible(boolean visible) { | |
471 | | |
472 |
1
1. setSelectionVisible : removed call to javax/swing/text/DefaultCaret::setSelectionVisible → NO_COVERAGE |
super.setSelectionVisible(true); |
473 | } | |
474 | }); | |
475 | ||
476 | // Side effect: disable caret blink, editable texts must restore blink rate | |
477 |
1
1. initialize : removed call to javax/swing/text/JTextComponent::addFocusListener → NO_COVERAGE |
component.addFocusListener(new FocusListener() { |
478 | ||
479 | @Override | |
480 | public void focusLost(FocusEvent e) { | |
481 | ||
482 |
1
1. focusLost : removed call to javax/swing/text/JTextComponent::setSelectionColor → NO_COVERAGE |
component.setSelectionColor(UiUtil.COLOR_FOCUS_LOST); |
483 |
1
1. focusLost : removed call to javax/swing/text/JTextComponent::revalidate → NO_COVERAGE |
component.revalidate(); |
484 |
1
1. focusLost : removed call to javax/swing/text/JTextComponent::repaint → NO_COVERAGE |
component.repaint(); |
485 | } | |
486 | ||
487 | @Override | |
488 | public void focusGained(FocusEvent e) { | |
489 | ||
490 |
1
1. focusGained : removed call to javax/swing/text/JTextComponent::setSelectionColor → NO_COVERAGE |
component.setSelectionColor(UiUtil.COLOR_FOCUS_GAINED); |
491 |
1
1. focusGained : removed call to javax/swing/text/JTextComponent::revalidate → NO_COVERAGE |
component.revalidate(); |
492 |
1
1. focusGained : removed call to javax/swing/text/JTextComponent::repaint → NO_COVERAGE |
component.repaint(); |
493 | } | |
494 | }); | |
495 | | |
496 |
1
1. initialize : removed call to javax/swing/ActionMap::put → NO_COVERAGE |
component.getActionMap().put(DefaultEditorKit.deletePrevCharAction, new DeletePrevCharAction()); |
497 |
1
1. initialize : removed call to javax/swing/ActionMap::put → NO_COVERAGE |
component.getActionMap().put(DefaultEditorKit.deleteNextCharAction, new DeleteNextCharAction()); |
498 | } | |
499 | | |
500 | /** | |
501 | * End the thread doing coloring. | |
502 | * @param textPane which coloring has to stop. | |
503 | */ | |
504 | public static void stopDocumentColorer(JTextPane textPane) { | |
505 | | |
506 |
1
1. stopDocumentColorer : negated conditional → NO_COVERAGE |
if (textPane.getStyledDocument() instanceof HighlightedDocument) { |
507 | | |
508 | HighlightedDocument oldDocument = (HighlightedDocument) textPane.getStyledDocument(); | |
509 |
1
1. stopDocumentColorer : removed call to com/jsql/view/swing/sql/lexer/HighlightedDocument::stopColorer → NO_COVERAGE |
oldDocument.stopColorer(); |
510 | } | |
511 | } | |
512 | } | |
Mutations | ||
207 |
1.1 |
|
208 |
1.1 |
|
209 |
1.1 |
|
210 |
1.1 |
|
211 |
1.1 |
|
219 |
1.1 |
|
220 |
1.1 |
|
221 |
1.1 |
|
222 |
1.1 |
|
223 |
1.1 |
|
289 |
1.1 |
|
291 |
1.1 |
|
293 |
1.1 |
|
320 |
1.1 |
|
357 |
1.1 |
|
358 |
1.1 |
|
362 |
1.1 2.2 3.3 |
|
432 |
1.1 |
|
436 |
1.1 2.2 |
|
443 |
1.1 |
|
451 |
1.1 2.2 3.3 4.4 5.5 |
|
453 |
1.1 |
|
454 |
1.1 |
|
456 |
1.1 |
|
458 |
1.1 |
|
459 |
1.1 2.2 3.3 |
|
460 |
1.1 |
|
467 |
1.1 |
|
472 |
1.1 |
|
477 |
1.1 |
|
482 |
1.1 |
|
483 |
1.1 |
|
484 |
1.1 |
|
490 |
1.1 |
|
491 |
1.1 |
|
492 |
1.1 |
|
496 |
1.1 |
|
497 |
1.1 |
|
506 |
1.1 |
|
509 |
1.1 |