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