UiUtil.java

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
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::loadFonts → NO_COVERAGE

208

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureToolTip → NO_COVERAGE

209

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureButton → NO_COVERAGE

210

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureMenu → NO_COVERAGE

211

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureTabbedPane → NO_COVERAGE

219

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureText → NO_COVERAGE

220

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureTable → NO_COVERAGE

221

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureTree → NO_COVERAGE

222

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureProgressBar → NO_COVERAGE

223

1.1
Location : prepareGUI
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::configureComboBox → NO_COVERAGE

289

1.1
Location : configureToolTip
Killed by : none
removed call to javax/swing/ToolTipManager::setInitialDelay → NO_COVERAGE

291

1.1
Location : configureToolTip
Killed by : none
removed call to javax/swing/ToolTipManager::setDismissDelay → NO_COVERAGE

293

1.1
Location : configureToolTip
Killed by : none
removed call to javax/swing/ToolTipManager::setReshowDelay → NO_COVERAGE

320

1.1
Location : configureMenu
Killed by : none
negated conditional → NO_COVERAGE

357

1.1
Location : paintBorder
Killed by : none
removed call to java/awt/Graphics2D::setColor → NO_COVERAGE

358

1.1
Location : paintBorder
Killed by : none
removed call to java/awt/Graphics2D::setStroke → NO_COVERAGE

362

1.1
Location : paintBorder
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : paintBorder
Killed by : none
removed call to java/awt/Graphics2D::drawRect → NO_COVERAGE

3.3
Location : paintBorder
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

432

1.1
Location : getIcons
Killed by : none
replaced return value with Collections.emptyList for com/jsql/view/swing/util/UiUtil::getIcons → NO_COVERAGE

436

1.1
Location : drawPlaceholder
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : drawPlaceholder
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::drawPlaceholder → NO_COVERAGE

443

1.1
Location : drawPlaceholder
Killed by : none
removed call to java/awt/Graphics2D::setRenderingHint → NO_COVERAGE

451

1.1
Location : drawPlaceholder
Killed by : none
Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE

2.2
Location : drawPlaceholder
Killed by : none
Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE

3.3
Location : drawPlaceholder
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

4.4
Location : drawPlaceholder
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

5.5
Location : drawPlaceholder
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

453

1.1
Location : drawPlaceholder
Killed by : none
removed call to java/awt/Graphics::setColor → NO_COVERAGE

454

1.1
Location : drawPlaceholder
Killed by : none
removed call to java/awt/Graphics::setFont → NO_COVERAGE

456

1.1
Location : drawPlaceholder
Killed by : none
removed call to java/awt/Graphics::drawString → NO_COVERAGE

458

1.1
Location : drawPlaceholder
Killed by : none
negated conditional → NO_COVERAGE

459

1.1
Location : drawPlaceholder
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : drawPlaceholder
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

3.3
Location : drawPlaceholder
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

460

1.1
Location : drawPlaceholder
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

467

1.1
Location : initialize
Killed by : none
removed call to javax/swing/text/JTextComponent::setCaret → NO_COVERAGE

472

1.1
Location : setSelectionVisible
Killed by : none
removed call to javax/swing/text/DefaultCaret::setSelectionVisible → NO_COVERAGE

477

1.1
Location : initialize
Killed by : none
removed call to javax/swing/text/JTextComponent::addFocusListener → NO_COVERAGE

482

1.1
Location : focusLost
Killed by : none
removed call to javax/swing/text/JTextComponent::setSelectionColor → NO_COVERAGE

483

1.1
Location : focusLost
Killed by : none
removed call to javax/swing/text/JTextComponent::revalidate → NO_COVERAGE

484

1.1
Location : focusLost
Killed by : none
removed call to javax/swing/text/JTextComponent::repaint → NO_COVERAGE

490

1.1
Location : focusGained
Killed by : none
removed call to javax/swing/text/JTextComponent::setSelectionColor → NO_COVERAGE

491

1.1
Location : focusGained
Killed by : none
removed call to javax/swing/text/JTextComponent::revalidate → NO_COVERAGE

492

1.1
Location : focusGained
Killed by : none
removed call to javax/swing/text/JTextComponent::repaint → NO_COVERAGE

496

1.1
Location : initialize
Killed by : none
removed call to javax/swing/ActionMap::put → NO_COVERAGE

497

1.1
Location : initialize
Killed by : none
removed call to javax/swing/ActionMap::put → NO_COVERAGE

506

1.1
Location : stopDocumentColorer
Killed by : none
negated conditional → NO_COVERAGE

509

1.1
Location : stopDocumentColorer
Killed by : none
removed call to com/jsql/view/swing/sql/lexer/HighlightedDocument::stopColorer → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1