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