HotkeyUtil.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.action;
12
13
import com.jsql.view.swing.menubar.Menubar;
14
import com.jsql.view.swing.util.MediatorHelper;
15
16
import javax.swing.*;
17
import java.awt.*;
18
import java.awt.event.ActionEvent;
19
import java.util.HashSet;
20
import java.util.Set;
21
22
/**
23
 * Keyword shortcut definition. <br>
24
 * - ctrl TAB: switch to next tab, <br>
25
 * - ctrl shift TAB: switch to previous tab, <br>
26
 * - ctrl W: delete tab
27
 */
28
public final class HotkeyUtil {
29
    
30
    private static final String STR_CTRL_TAB = "ctrl TAB";
31
    private static final String STR_CTRL_SHIFT_TAB = "ctrl shift TAB";
32
    private static final String STR_SELECT_TAB = "actionString-selectTab";
33
    
34
    private HotkeyUtil() {
35
        // Utility class
36
    }
37
    
38
    /**
39
     * Select all textfield content when focused.
40
     */
41
    public static void addTextFieldShortcutSelectAll() {
42
        
43 1 1. addTextFieldShortcutSelectAll : removed call to java/awt/KeyboardFocusManager::addPropertyChangeListener → NO_COVERAGE
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(
44
            "permanentFocusOwner",
45
            propertyChangeEvent -> {
46 1 1. lambda$addTextFieldShortcutSelectAll$1 : negated conditional → NO_COVERAGE
                if (propertyChangeEvent.getNewValue() instanceof JTextField) {
47 1 1. lambda$addTextFieldShortcutSelectAll$1 : removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE
                    SwingUtilities.invokeLater(() -> {
48
                        
49
                        JTextField textField = (JTextField) propertyChangeEvent.getNewValue();
50 1 1. lambda$addTextFieldShortcutSelectAll$0 : removed call to javax/swing/JTextField::selectAll → NO_COVERAGE
                        textField.selectAll();
51
                    });
52
                }
53
            }
54
        );
55
    }
56
    
57
    /**
58
     * Add action to a single tabbedpane (ctrl-tab, ctrl-shift-tab).
59
     */
60
    public static void addShortcut(JTabbedPane tabbedPane) {
61
        
62
        var ctrlTab = KeyStroke.getKeyStroke(STR_CTRL_TAB);
63
        var ctrlShiftTab = KeyStroke.getKeyStroke(STR_CTRL_SHIFT_TAB);
64
65
        // Remove ctrl-tab from normal focus traversal
66
        Set<AWTKeyStroke> forwardKeys = new HashSet<>(tabbedPane.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
67
        forwardKeys.remove(ctrlTab);
68 1 1. addShortcut : removed call to javax/swing/JTabbedPane::setFocusTraversalKeys → NO_COVERAGE
        tabbedPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
69
70
        // Remove ctrl-shift-tab from normal focus traversal
71
        Set<AWTKeyStroke> backwardKeys = new HashSet<>(tabbedPane.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
72
        backwardKeys.remove(ctrlShiftTab);
73 1 1. addShortcut : removed call to javax/swing/JTabbedPane::setFocusTraversalKeys → NO_COVERAGE
        tabbedPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
74
75
        // Add keys to the tab's input map
76
        var inputMap = tabbedPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
77 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
        inputMap.put(ctrlTab, "navigateNext");
78 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
        inputMap.put(ctrlShiftTab, "navigatePrevious");
79
    }
80
    
81
    /**
82
     * Add action to global root (ctrl-tab, ctrl-shift-tab, ctrl-W).
83
     */
84
        public static void addShortcut(JRootPane rootPane, final JTabbedPane valuesTabbedPane) {
85
        
86
        Action closeTab = new ActionCloseTabResult();
87
        
88
        Action nextTab = new AbstractAction() {
89
            
90
            @Override
91
            public void actionPerformed(ActionEvent e) {
92 2 1. actionPerformed : changed conditional boundary → NO_COVERAGE
2. actionPerformed : negated conditional → NO_COVERAGE
                if (valuesTabbedPane.getTabCount() > 0) {
93
                    
94
                    int selectedIndex = valuesTabbedPane.getSelectedIndex();
95
                    
96 3 1. actionPerformed : Replaced integer addition with subtraction → NO_COVERAGE
2. actionPerformed : changed conditional boundary → NO_COVERAGE
3. actionPerformed : negated conditional → NO_COVERAGE
                    if (selectedIndex + 1 < valuesTabbedPane.getTabCount()) {
97 2 1. actionPerformed : Replaced integer addition with subtraction → NO_COVERAGE
2. actionPerformed : removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE
                        valuesTabbedPane.setSelectedIndex(selectedIndex + 1);
98
                    } else {
99 1 1. actionPerformed : removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE
                        valuesTabbedPane.setSelectedIndex(0);
100
                    }
101
                }
102
            }
103
        };
104
        
105
        Action previousTab = new AbstractAction() {
106
            
107
            @Override
108
            public void actionPerformed(ActionEvent e) {
109 2 1. actionPerformed : changed conditional boundary → NO_COVERAGE
2. actionPerformed : negated conditional → NO_COVERAGE
                if (valuesTabbedPane.getTabCount() > 0) {
110
                    
111
                    int selectedIndex = valuesTabbedPane.getSelectedIndex();
112
                    
113 3 1. actionPerformed : Replaced integer subtraction with addition → NO_COVERAGE
2. actionPerformed : changed conditional boundary → NO_COVERAGE
3. actionPerformed : negated conditional → NO_COVERAGE
                    if (selectedIndex - 1 > -1) {
114 2 1. actionPerformed : removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE
2. actionPerformed : Replaced integer subtraction with addition → NO_COVERAGE
                        valuesTabbedPane.setSelectedIndex(selectedIndex - 1);
115
                    } else {
116 2 1. actionPerformed : Replaced integer subtraction with addition → NO_COVERAGE
2. actionPerformed : removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE
                        valuesTabbedPane.setSelectedIndex(valuesTabbedPane.getTabCount() - 1);
117
                    }
118
                }
119
            }
120
        };
121
        
122
        Set<AWTKeyStroke> forwardKeys = new HashSet<>(rootPane.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
123
        forwardKeys.remove(KeyStroke.getKeyStroke(STR_CTRL_TAB));
124 1 1. addShortcut : removed call to javax/swing/JRootPane::setFocusTraversalKeys → NO_COVERAGE
        rootPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
125
        
126
        Set<AWTKeyStroke> backwardKeys = new HashSet<>(rootPane.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
127
        backwardKeys.remove(KeyStroke.getKeyStroke(STR_CTRL_SHIFT_TAB));
128 1 1. addShortcut : removed call to javax/swing/JRootPane::setFocusTraversalKeys → NO_COVERAGE
        rootPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
129
        
130
        var inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
131
        var actionMap = rootPane.getActionMap();
132
133 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
        inputMap.put(KeyStroke.getKeyStroke("ctrl W"), "actionString-closeTab");
134 1 1. addShortcut : removed call to javax/swing/ActionMap::put → NO_COVERAGE
        actionMap.put("actionString-closeTab", closeTab);
135
        
136 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
        inputMap.put(KeyStroke.getKeyStroke(STR_CTRL_TAB), "actionString-nextTab");
137 1 1. addShortcut : removed call to javax/swing/ActionMap::put → NO_COVERAGE
        actionMap.put("actionString-nextTab", nextTab);
138
139 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
        inputMap.put(KeyStroke.getKeyStroke(STR_CTRL_SHIFT_TAB), "actionString-previousTab");
140 1 1. addShortcut : removed call to javax/swing/ActionMap::put → NO_COVERAGE
        actionMap.put("actionString-previousTab", previousTab);
141
        
142
        int tabCount = MediatorHelper.tabManagers().getTabCount();
143
        
144 2 1. addShortcut : changed conditional boundary → NO_COVERAGE
2. addShortcut : negated conditional → NO_COVERAGE
        for (var currentTab = 1 ; currentTab <= tabCount ; currentTab++) {
145
            
146 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
            inputMap.put(KeyStroke.getKeyStroke("ctrl "+ currentTab), STR_SELECT_TAB + currentTab);
147 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
            inputMap.put(KeyStroke.getKeyStroke("ctrl NUMPAD"+ currentTab), STR_SELECT_TAB + currentTab);
148
            
149
            final int currentTabFinal = currentTab;
150 1 1. addShortcut : removed call to javax/swing/ActionMap::put → NO_COVERAGE
            actionMap.put(STR_SELECT_TAB + currentTab, new AbstractAction() {
151
                @Override
152
                public void actionPerformed(ActionEvent e) {
153 2 1. actionPerformed : removed call to com/jsql/view/swing/tab/TabManagersProxy::setSelectedIndex → NO_COVERAGE
2. actionPerformed : Replaced integer subtraction with addition → NO_COVERAGE
                    MediatorHelper.tabManagers().setSelectedIndex(currentTabFinal - 1);
154
                }
155
            });
156
        }
157
        
158 1 1. addShortcut : removed call to javax/swing/InputMap::put → NO_COVERAGE
        inputMap.put(KeyStroke.getKeyStroke("ctrl S"), "actionString-saveTab");
159 1 1. addShortcut : removed call to javax/swing/ActionMap::put → NO_COVERAGE
        actionMap.put("actionString-saveTab", new ActionSaveTab());
160
    }
161
162
    /**
163
     * Create Alt shortcut to display menubar ; remove menubar when focus is set to a component.
164
     * @param menubar The menubar to display
165
     */
166
    public static void addShortcut(final Menubar menubar) {
167
        
168
        /* Hide Menubar when focusing any component */
169 1 1. addShortcut : removed call to java/awt/KeyboardFocusManager::addPropertyChangeListener → NO_COVERAGE
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(
170
            "permanentFocusOwner",
171 1 1. lambda$addShortcut$3 : removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE
            propertyChangeEvent -> SwingUtilities.invokeLater(() -> {
172
                if (
173
                    // Fix #40924: NullPointerException on MediatorGui.panelAddressBar()
174 1 1. lambda$addShortcut$2 : negated conditional → NO_COVERAGE
                    MediatorHelper.panelAddressBar() != null
175 1 1. lambda$addShortcut$2 : negated conditional → NO_COVERAGE
                    && !MediatorHelper.panelAddressBar().isAdvanceActivated()
176
                ) {
177 1 1. lambda$addShortcut$2 : removed call to com/jsql/view/swing/menubar/Menubar::setVisible → NO_COVERAGE
                    menubar.setVisible(false);
178
                }
179
            })
180
        );
181
        
182
        /* Show/Hide the Menubar with Alt key (not Alt Graph) */
183 1 1. addShortcut : removed call to java/awt/KeyboardFocusManager::addKeyEventDispatcher → NO_COVERAGE
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
184
            new AltKeyEventDispatcher()
185
        );
186
    }
187
}

Mutations

43

1.1
Location : addTextFieldShortcutSelectAll
Killed by : none
removed call to java/awt/KeyboardFocusManager::addPropertyChangeListener → NO_COVERAGE

46

1.1
Location : lambda$addTextFieldShortcutSelectAll$1
Killed by : none
negated conditional → NO_COVERAGE

47

1.1
Location : lambda$addTextFieldShortcutSelectAll$1
Killed by : none
removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE

50

1.1
Location : lambda$addTextFieldShortcutSelectAll$0
Killed by : none
removed call to javax/swing/JTextField::selectAll → NO_COVERAGE

68

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/JTabbedPane::setFocusTraversalKeys → NO_COVERAGE

73

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/JTabbedPane::setFocusTraversalKeys → NO_COVERAGE

77

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

78

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

92

1.1
Location : actionPerformed
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : actionPerformed
Killed by : none
negated conditional → NO_COVERAGE

96

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

2.2
Location : actionPerformed
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : actionPerformed
Killed by : none
negated conditional → NO_COVERAGE

97

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

2.2
Location : actionPerformed
Killed by : none
removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE

99

1.1
Location : actionPerformed
Killed by : none
removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE

109

1.1
Location : actionPerformed
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : actionPerformed
Killed by : none
negated conditional → NO_COVERAGE

113

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

2.2
Location : actionPerformed
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : actionPerformed
Killed by : none
negated conditional → NO_COVERAGE

114

1.1
Location : actionPerformed
Killed by : none
removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE

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

116

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

2.2
Location : actionPerformed
Killed by : none
removed call to javax/swing/JTabbedPane::setSelectedIndex → NO_COVERAGE

124

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/JRootPane::setFocusTraversalKeys → NO_COVERAGE

128

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/JRootPane::setFocusTraversalKeys → NO_COVERAGE

133

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

134

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

136

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

137

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

139

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

140

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

144

1.1
Location : addShortcut
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : addShortcut
Killed by : none
negated conditional → NO_COVERAGE

146

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

147

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

150

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

153

1.1
Location : actionPerformed
Killed by : none
removed call to com/jsql/view/swing/tab/TabManagersProxy::setSelectedIndex → NO_COVERAGE

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

158

1.1
Location : addShortcut
Killed by : none
removed call to javax/swing/InputMap::put → NO_COVERAGE

159

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

169

1.1
Location : addShortcut
Killed by : none
removed call to java/awt/KeyboardFocusManager::addPropertyChangeListener → NO_COVERAGE

171

1.1
Location : lambda$addShortcut$3
Killed by : none
removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE

174

1.1
Location : lambda$addShortcut$2
Killed by : none
negated conditional → NO_COVERAGE

175

1.1
Location : lambda$addShortcut$2
Killed by : none
negated conditional → NO_COVERAGE

177

1.1
Location : lambda$addShortcut$2
Killed by : none
removed call to com/jsql/view/swing/menubar/Menubar::setVisible → NO_COVERAGE

183

1.1
Location : addShortcut
Killed by : none
removed call to java/awt/KeyboardFocusManager::addKeyEventDispatcher → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1