MouseAdapterMenuAction.java

1
/*******************************************************************************
2
 * Copyhacked (H) 2012-2025.
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 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.list;
12
13
import com.formdev.flatlaf.util.SystemFileChooser;
14
import com.jsql.util.I18nUtil;
15
import com.jsql.util.LogLevelUtil;
16
import com.jsql.view.swing.util.I18nViewUtil;
17
import com.jsql.view.swing.util.MediatorHelper;
18
import org.apache.logging.log4j.LogManager;
19
import org.apache.logging.log4j.Logger;
20
21
import javax.swing.*;
22
import java.awt.*;
23
import java.awt.event.*;
24
import java.io.IOException;
25
import java.util.AbstractMap.SimpleEntry;
26
import java.util.Arrays;
27
import java.util.stream.Stream;
28
29
/**
30
 * A Mouse action to display a popupmenu on a JList.
31
 */
32
public class MouseAdapterMenuAction extends MouseAdapter {
33
    
34
    private static final Logger LOGGER = LogManager.getRootLogger();
35
    
36
    /**
37
     * JList to add popupmenu.
38
     */
39
    private final DnDList dndList;
40
    
41
    /**
42
     * Create a popup menu for current JList item.
43
     * @param dndList List with action
44
     */
45
    public MouseAdapterMenuAction(DnDList dndList) {
46
        this.dndList = dndList;
47
    }
48
    
49
    /**
50
     * Displays a popup menu for JList.
51
     * @param mouseEvent Mouse event
52
     */
53
    @SuppressWarnings("unchecked")
54
    public void showPopup(final MouseEvent mouseEvent) {
55 1 1. showPopup : negated conditional → NO_COVERAGE
        if (mouseEvent.isPopupTrigger()) {
56
            JList<ItemList> list = (JList<ItemList>) mouseEvent.getSource();
57
58
            JPopupMenu popupMenuList = this.initMenu(mouseEvent);
59 1 1. showPopup : removed call to javax/swing/JPopupMenu::applyComponentOrientation → NO_COVERAGE
            popupMenuList.applyComponentOrientation(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()));
60
            // Fix #26274: IllegalComponentStateException on show()
61
            try {
62 1 1. showPopup : removed call to javax/swing/JPopupMenu::show → NO_COVERAGE
                popupMenuList.show(
63
                    list,
64 1 1. showPopup : negated conditional → NO_COVERAGE
                    ComponentOrientation.RIGHT_TO_LEFT.equals(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()))
65 1 1. showPopup : Replaced integer subtraction with addition → NO_COVERAGE
                    ? mouseEvent.getX() - popupMenuList.getWidth()
66
                    : mouseEvent.getX(),
67
                    mouseEvent.getY()
68
                );
69
            } catch (IllegalComponentStateException e) {
70
                LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
71
            }
72
            
73 1 1. showPopup : removed call to javax/swing/JPopupMenu::setLocation → NO_COVERAGE
            popupMenuList.setLocation(
74 1 1. showPopup : negated conditional → NO_COVERAGE
                ComponentOrientation.RIGHT_TO_LEFT.equals(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()))
75 1 1. showPopup : Replaced integer subtraction with addition → NO_COVERAGE
                ? mouseEvent.getXOnScreen() - popupMenuList.getWidth()
76
                : mouseEvent.getXOnScreen(),
77
                mouseEvent.getYOnScreen()
78
            );
79
        }
80
    }
81
82
    private JPopupMenu initMenu(final MouseEvent mouseEvent) {
83
        var popupMenuList = new JPopupMenu();
84
        
85
        boolean isNonUbuntu = I18nViewUtil.isNonUbuntu(I18nUtil.getCurrentLocale());
86
        
87
        JMenuItem menuImport = new JMenuItem();
88
        JMenuItem menuExport = new JMenuItem();
89
        JMenuItem menuCut = new JMenuItem();
90
        JMenuItem menuCopy = new JMenuItem();
91
        JMenuItem menuPaste = new JMenuItem();
92
        JMenuItem menuDelete = new JMenuItem();
93
        JMenuItem menuNew = new JMenuItem();
94
        JMenuItem menuRestoreDefault = new JMenuItem();
95
        JMenuItem menuSelectAll = new JMenuItem();
96
        
97
        Stream.of(
98
            new SimpleEntry<>(menuImport, "LIST_IMPORT_CONFIRM_TITLE"),
99
            new SimpleEntry<>(menuExport, "LIST_EXPORT_TITLE"),
100
            new SimpleEntry<>(menuCut, "LIST_CUT"),
101
            new SimpleEntry<>(menuCopy, "CONTEXT_MENU_COPY"),
102
            new SimpleEntry<>(menuPaste, "LIST_PASTE"),
103
            new SimpleEntry<>(menuDelete, "LIST_DELETE"),
104
            new SimpleEntry<>(menuNew, "LIST_NEW_VALUE"),
105
            new SimpleEntry<>(menuRestoreDefault, "LIST_RESTORE_DEFAULT"),
106
            new SimpleEntry<>(menuSelectAll, "CONTEXT_MENU_SELECT_ALL")
107
        )
108 1 1. initMenu : removed call to java/util/stream/Stream::forEach → NO_COVERAGE
        .forEach(entry -> {
109 1 1. lambda$initMenu$0 : removed call to javax/swing/JMenuItem::setText → NO_COVERAGE
            entry.getKey().setText(
110 1 1. lambda$initMenu$0 : negated conditional → NO_COVERAGE
                isNonUbuntu
111
                ? I18nViewUtil.valueByKey(entry.getValue())
112
                : I18nUtil.valueByKey(entry.getValue())
113
            );
114 1 1. lambda$initMenu$0 : removed call to javax/swing/JMenuItem::setName → NO_COVERAGE
            entry.getKey().setName(entry.getValue());
115 1 1. lambda$initMenu$0 : removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE
            I18nViewUtil.addComponentForKey(entry.getValue(), entry.getKey());
116
        });
117
118 1 1. initMenu : removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE
        menuCut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK));
119 1 1. initMenu : removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE
        menuCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK));
120 1 1. initMenu : removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE
        menuPaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK));
121 1 1. initMenu : removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE
        menuSelectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
122
        
123
        final var importFileDialog = new SystemFileChooser(MediatorHelper.model().getMediatorUtils().preferencesUtil().getPathFile());
124 1 1. initMenu : removed call to com/formdev/flatlaf/util/SystemFileChooser::setDialogTitle → NO_COVERAGE
        importFileDialog.setDialogTitle(I18nUtil.valueByKey("LIST_IMPORT_CONFIRM_TITLE"));
125 1 1. initMenu : removed call to com/formdev/flatlaf/util/SystemFileChooser::setMultiSelectionEnabled → NO_COVERAGE
        importFileDialog.setMultiSelectionEnabled(true);
126
127 1 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuNew.addActionListener(new MenuActionNewValue(this.dndList));
128
129 1 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuImport.addActionListener(actionEvent -> {
130
            var choice = 0;
131
            // Fix #1896: NullPointerException on showOpenDialog()
132
            // Fix #42831: ClassCastException on showOpenDialog()
133
            try {
134
                choice = importFileDialog.showOpenDialog(this.dndList.getTopLevelAncestor());
135 1 1. lambda$initMenu$1 : negated conditional → NO_COVERAGE
                if (choice == JFileChooser.APPROVE_OPTION) {
136 1 1. lambda$initMenu$1 : removed call to com/jsql/view/swing/list/DnDList::dropPasteFile → NO_COVERAGE
                    this.dndList.dropPasteFile(
137
                        Arrays.asList(importFileDialog.getSelectedFiles()),
138
                        this.dndList.locationToIndex(mouseEvent.getPoint())
139
                    );
140
                }
141
            } catch (ClassCastException | NullPointerException | IOException e) {
142
                LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
143
            }
144
        });
145
146 1 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuCopy.addActionListener(actionEvent -> {
147
            var action = this.dndList.getActionMap().get(TransferHandler.getCopyAction().getValue(Action.NAME));
148 1 1. lambda$initMenu$2 : negated conditional → NO_COVERAGE
            if (action != null) {
149 1 1. lambda$initMenu$2 : removed call to javax/swing/Action::actionPerformed → NO_COVERAGE
                action.actionPerformed(
150
                    new ActionEvent(this.dndList, ActionEvent.ACTION_PERFORMED, null)
151
                );
152
            }
153
        });
154
155 1 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuCut.addActionListener(actionEvent -> {
156
            var action = this.dndList.getActionMap().get(TransferHandler.getCutAction().getValue(Action.NAME));
157 1 1. lambda$initMenu$3 : negated conditional → NO_COVERAGE
            if (action != null) {
158 1 1. lambda$initMenu$3 : removed call to javax/swing/Action::actionPerformed → NO_COVERAGE
                action.actionPerformed(
159
                    new ActionEvent(this.dndList, ActionEvent.ACTION_PERFORMED, null)
160
                );
161
            }
162
        });
163
164 1 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuPaste.addActionListener(actionEvent -> {
165
            var action = this.dndList.getActionMap().get(TransferHandler.getPasteAction().getValue(Action.NAME));
166 1 1. lambda$initMenu$4 : negated conditional → NO_COVERAGE
            if (action != null) {
167 1 1. lambda$initMenu$4 : removed call to javax/swing/Action::actionPerformed → NO_COVERAGE
                action.actionPerformed(
168
                    new ActionEvent(this.dndList, ActionEvent.ACTION_PERFORMED, null)
169
                );
170
            }
171
        });
172
173 2 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
2. lambda$initMenu$5 : removed call to com/jsql/view/swing/list/DnDList::removeSelectedItem → NO_COVERAGE
        menuDelete.addActionListener(actionEvent -> this.dndList.removeSelectedItem());
174 1 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuExport.addActionListener(new MenuActionExport(this.dndList));
175 2 1. initMenu : removed call to javax/swing/JMenuItem::setEnabled → NO_COVERAGE
2. initMenu : negated conditional → NO_COVERAGE
        menuExport.setEnabled(!this.dndList.listModel.isEmpty());
176 2 1. lambda$initMenu$6 : removed call to com/jsql/view/swing/list/DnDList::restore → NO_COVERAGE
2. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuRestoreDefault.addActionListener(actionEvent -> this.dndList.restore());
177 1 1. initMenu : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        menuSelectAll.addActionListener(actionEvent -> {
178
            var start = 0;
179 1 1. lambda$initMenu$7 : Replaced integer subtraction with addition → NO_COVERAGE
            int end = this.dndList.getModel().getSize() - 1;
180 2 1. lambda$initMenu$7 : changed conditional boundary → NO_COVERAGE
2. lambda$initMenu$7 : negated conditional → NO_COVERAGE
            if (end >= 0) {
181 1 1. lambda$initMenu$7 : removed call to com/jsql/view/swing/list/DnDList::setSelectionInterval → NO_COVERAGE
                this.dndList.setSelectionInterval(start, end);
182
            }
183
        });
184
185
        popupMenuList.add(menuNew);
186
        popupMenuList.add(new JSeparator());
187
        popupMenuList.add(menuCut);
188
        popupMenuList.add(menuCopy);
189
        popupMenuList.add(menuPaste);
190
        popupMenuList.add(menuDelete);
191
        popupMenuList.add(new JSeparator());
192
        popupMenuList.add(menuSelectAll);
193
        popupMenuList.add(new JSeparator());
194
        popupMenuList.add(menuImport);
195
        popupMenuList.add(menuExport);
196
        popupMenuList.add(new JSeparator());
197
        popupMenuList.add(menuRestoreDefault);
198 1 1. initMenu : replaced return value with null for com/jsql/view/swing/list/MouseAdapterMenuAction::initMenu → NO_COVERAGE
        return popupMenuList;
199
    }
200
201
    @Override
202
    public void mousePressed(MouseEvent e) {
203 1 1. mousePressed : negated conditional → NO_COVERAGE
        if (SwingUtilities.isRightMouseButton(e)) {
204
            int clickIndex = this.dndList.locationToIndex(e.getPoint());
205
            var containsIndex = false;
206
            for (int currentIndex: this.dndList.getSelectedIndices()) {
207 1 1. mousePressed : negated conditional → NO_COVERAGE
                if (currentIndex == clickIndex) {
208
                    containsIndex = true;
209
                    break;
210
                }
211
            }
212 1 1. mousePressed : negated conditional → NO_COVERAGE
            if (!containsIndex) {
213 1 1. mousePressed : removed call to com/jsql/view/swing/list/DnDList::setSelectedIndex → NO_COVERAGE
                this.dndList.setSelectedIndex(clickIndex);
214
            }
215
        }
216 1 1. mousePressed : removed call to com/jsql/view/swing/list/MouseAdapterMenuAction::showPopup → NO_COVERAGE
        this.showPopup(e);
217
    }
218
219
    @Override
220
    public void mouseReleased(MouseEvent e) {
221 1 1. mouseReleased : removed call to com/jsql/view/swing/list/MouseAdapterMenuAction::showPopup → NO_COVERAGE
        this.showPopup(e);
222
    }
223
}

Mutations

55

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

59

1.1
Location : showPopup
Killed by : none
removed call to javax/swing/JPopupMenu::applyComponentOrientation → NO_COVERAGE

62

1.1
Location : showPopup
Killed by : none
removed call to javax/swing/JPopupMenu::show → NO_COVERAGE

64

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

65

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

73

1.1
Location : showPopup
Killed by : none
removed call to javax/swing/JPopupMenu::setLocation → NO_COVERAGE

74

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

75

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

108

1.1
Location : initMenu
Killed by : none
removed call to java/util/stream/Stream::forEach → NO_COVERAGE

109

1.1
Location : lambda$initMenu$0
Killed by : none
removed call to javax/swing/JMenuItem::setText → NO_COVERAGE

110

1.1
Location : lambda$initMenu$0
Killed by : none
negated conditional → NO_COVERAGE

114

1.1
Location : lambda$initMenu$0
Killed by : none
removed call to javax/swing/JMenuItem::setName → NO_COVERAGE

115

1.1
Location : lambda$initMenu$0
Killed by : none
removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE

118

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE

119

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE

120

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE

121

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE

124

1.1
Location : initMenu
Killed by : none
removed call to com/formdev/flatlaf/util/SystemFileChooser::setDialogTitle → NO_COVERAGE

125

1.1
Location : initMenu
Killed by : none
removed call to com/formdev/flatlaf/util/SystemFileChooser::setMultiSelectionEnabled → NO_COVERAGE

127

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

129

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

135

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

136

1.1
Location : lambda$initMenu$1
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::dropPasteFile → NO_COVERAGE

146

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

148

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

149

1.1
Location : lambda$initMenu$2
Killed by : none
removed call to javax/swing/Action::actionPerformed → NO_COVERAGE

155

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

157

1.1
Location : lambda$initMenu$3
Killed by : none
negated conditional → NO_COVERAGE

158

1.1
Location : lambda$initMenu$3
Killed by : none
removed call to javax/swing/Action::actionPerformed → NO_COVERAGE

164

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

166

1.1
Location : lambda$initMenu$4
Killed by : none
negated conditional → NO_COVERAGE

167

1.1
Location : lambda$initMenu$4
Killed by : none
removed call to javax/swing/Action::actionPerformed → NO_COVERAGE

173

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

2.2
Location : lambda$initMenu$5
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::removeSelectedItem → NO_COVERAGE

174

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

175

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::setEnabled → NO_COVERAGE

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

176

1.1
Location : lambda$initMenu$6
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::restore → NO_COVERAGE

2.2
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

177

1.1
Location : initMenu
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

179

1.1
Location : lambda$initMenu$7
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

180

1.1
Location : lambda$initMenu$7
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : lambda$initMenu$7
Killed by : none
negated conditional → NO_COVERAGE

181

1.1
Location : lambda$initMenu$7
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::setSelectionInterval → NO_COVERAGE

198

1.1
Location : initMenu
Killed by : none
replaced return value with null for com/jsql/view/swing/list/MouseAdapterMenuAction::initMenu → NO_COVERAGE

203

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

207

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

212

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

213

1.1
Location : mousePressed
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::setSelectedIndex → NO_COVERAGE

216

1.1
Location : mousePressed
Killed by : none
removed call to com/jsql/view/swing/list/MouseAdapterMenuAction::showPopup → NO_COVERAGE

221

1.1
Location : mouseReleased
Killed by : none
removed call to com/jsql/view/swing/list/MouseAdapterMenuAction::showPopup → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.22.1