Skip to content

Commit 5619756

Browse files
Upgrade ui feel.
1 parent 1b677b7 commit 5619756

9 files changed

Lines changed: 176 additions & 34 deletions

File tree

src/main/java/com/artur114/bytecodegrab/agent/Grabber.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.artur114.bytecodegrab.agent;
22

3+
import java.io.EOFException;
34
import java.io.IOException;
45
import java.lang.instrument.Instrumentation;
56
import java.lang.instrument.UnmodifiableClassException;
@@ -48,6 +49,7 @@ public void run() {
4849
LOGGER.warn("Wrong message: {}", message);
4950
}
5051
}
52+
} catch (EOFException ignored) {
5153
} catch (IOException e) {
5254
e.printStackTrace(System.err);
5355
} finally {

src/main/java/com/artur114/bytecodegrab/jcomp/JClassTree.java

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
import javax.swing.Timer;
99
import javax.swing.tree.*;
1010
import java.awt.*;
11+
import java.awt.event.MouseAdapter;
12+
import java.awt.event.MouseEvent;
13+
import java.awt.event.MouseListener;
14+
import java.awt.event.MouseMotionListener;
1115
import java.util.List;
1216
import java.util.*;
1317

@@ -18,6 +22,7 @@ public class JClassTree extends JPanel {
1822
private AsyncClassTreeBuilder builder;
1923
private String currentFilter;
2024
public boolean keepExpanded = false;
25+
private JPopupMenu popup;
2126
public final JTree tree;
2227

2328
public JClassTree() {
@@ -28,6 +33,72 @@ public JClassTree() {
2833
this.tree.setShowsRootHandles(true);
2934
this.tree.setCellRenderer(new ClassTreeCellRenderer());
3035
this.tree.collapseRow(0);
36+
this.tree.addMouseListener(new MouseAdapter() {
37+
38+
@Override
39+
public void mouseReleased(MouseEvent e) {
40+
if (popup != null && e.isPopupTrigger() && SwingUtilities.isRightMouseButton(e)) {
41+
Rectangle r = allRowsRectangle(tree);
42+
int row = tree.getRowForLocation(e.getX(), e.getY());
43+
boolean outOfBounds = !r.contains(e.getPoint()) || row == -1;
44+
45+
if (!outOfBounds) {
46+
tree.requestFocusInWindow();
47+
popup.show(tree, e.getX(), e.getY());
48+
tree.setSelectionRow(row);
49+
}
50+
}
51+
}
52+
53+
@Override
54+
public void mouseClicked(MouseEvent e) {
55+
if (popup != null && e.isPopupTrigger() && SwingUtilities.isRightMouseButton(e)) {
56+
Rectangle r = allRowsRectangle(tree);
57+
int row = tree.getRowForLocation(e.getX(), e.getY());
58+
boolean outOfBounds = !r.contains(e.getPoint()) || row == -1;
59+
60+
if (!outOfBounds) {
61+
tree.requestFocusInWindow();
62+
popup.show(tree, e.getX(), e.getY());
63+
tree.setSelectionRow(row);
64+
}
65+
}
66+
}
67+
68+
@Override
69+
public void mousePressed(MouseEvent e) {
70+
Rectangle r = allRowsRectangle(tree);
71+
int row = tree.getRowForLocation(e.getX(), e.getY());
72+
boolean outOfBounds = !r.contains(e.getPoint()) || row == -1;
73+
if (SwingUtilities.isLeftMouseButton(e)) {
74+
if (outOfBounds) {
75+
tree.clearSelection();
76+
tree.getParent().requestFocusInWindow();
77+
} else {
78+
tree.requestFocusInWindow();
79+
}
80+
}
81+
if (!outOfBounds && popup != null && e.isPopupTrigger() && SwingUtilities.isRightMouseButton(e)) {
82+
tree.requestFocusInWindow();
83+
popup.show(tree, e.getX(), e.getY());
84+
tree.setSelectionRow(row);
85+
}
86+
}
87+
88+
private Rectangle allRowsRectangle(JTree tree) {
89+
if (tree.getRowCount() <= 0) {
90+
return new Rectangle();
91+
}
92+
Rectangle ret = tree.getRowBounds(0);
93+
if (tree.getRowCount() > 1) {
94+
for (int i = 1; i != tree.getRowCount(); i++) {
95+
ret.add(tree.getRowBounds(i));
96+
}
97+
}
98+
return ret;
99+
}
100+
});
101+
31102
JScrollPane pane = new JScrollPane(this.tree);
32103
pane.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
33104
this.add(pane, BorderLayout.CENTER);
@@ -98,6 +169,7 @@ public AsyncClassTreeBuilder updateTree(Set<String> classNames) {
98169

99170
public void clear() {
100171
((DefaultMutableTreeNode) this.treeModel.getRoot()).removeAllChildren();
172+
this.loadedClasses.clear();
101173
this.treeModel.reload();
102174
}
103175

@@ -169,14 +241,19 @@ public void collapseAll() {
169241
}
170242

171243
public void expandChild(TreePath path, DefaultMutableTreeNode parent) {
244+
this.tree.expandPath(path);
245+
172246
for (DefaultMutableTreeNode node : this.child(parent)) {
173247
TreePath newPath = path.pathByAddingChild(node);
174-
this.tree.expandPath(newPath);
175-
176248
this.expandChild(newPath, node);
177249
}
178250
}
179251

252+
@Override
253+
public void setComponentPopupMenu(JPopupMenu popup) {
254+
this.popup = popup;
255+
}
256+
180257
private void fillClasses(List<String> list, DefaultMutableTreeNode node) {
181258
Object obj = node.getUserObject();
182259

src/main/java/com/artur114/bytecodegrab/jcomp/JGrabFrame.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
import java.io.File;
1111

1212
public class JGrabFrame extends JFrame {
13-
private final IListenBuss<IListener<IGrabStartData>, IGrabStartData> grabListenBuss = new ArrayListenBuss<>();
14-
private final IListenBuss<IListener<Void>, Void> grabAbortListenBuss = new ArrayListenBuss<>();
15-
private final IListenBuss<IListener<Void>, Void> frameCloseListenBuss = new ArrayListenBuss<>();
13+
private final IListenBuss<IListener<IGrabStartData>, IGrabStartData> grabListenBuss = new ArrayEDITListenBuss<>();
14+
private final IListenBuss<IListener<Void>, Void> grabAbortListenBuss = new ArrayEDITListenBuss<>();
15+
private final IListenBuss<IListener<Void>, Void> frameCloseListenBuss = new ArrayEDITListenBuss<>();
1616
private final JCardContainer card;
1717
private boolean isDone = false;
1818
private JProgressBar progress;

src/main/java/com/artur114/bytecodegrab/model/CodeGrabModel.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
import java.util.List;
77

88
public class CodeGrabModel {
9-
private final IListenBuss<IListener<List<String>>, List<String>> classesRequestDoneBuss = new ArrayListenBuss<>();
10-
private final IListenBuss<IListener<Percent>, Percent> classesRequestProcessBuss = new ArrayListenBuss<>();
9+
private final IListenBuss<IListener<List<String>>, List<String>> classesRequestDoneBuss = new ArrayEDITListenBuss<>();
10+
private final IListenBuss<IListener<Percent>, Percent> classesRequestProcessBuss = new ArrayEDITListenBuss<>();
1111

12-
private final IListenBuss<IListener<AsyncByteCodeWriter.IGrabState>, AsyncByteCodeWriter.IGrabState> bytecodeRequestProcessBuss = new ArrayListenBuss<>();
13-
private final IListenBuss<IListener<File>, File> bytecodeRequestDoneBuss = new ArrayListenBuss<>();
12+
private final IListenBuss<IListener<AsyncByteCodeWriter.IGrabState>, AsyncByteCodeWriter.IGrabState> bytecodeRequestProcessBuss = new ArrayEDITListenBuss<>();
13+
private final IListenBuss<IListener<File>, File> bytecodeRequestDoneBuss = new ArrayEDITListenBuss<>();
1414

1515
private AsyncClassesRequester requester;
1616
private AsyncByteCodeWriter writer;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.artur114.bytecodegrab.util;
2+
3+
import javax.swing.*;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
7+
public class ArrayEDITListenBuss<L extends IListener<V>, V> implements IListenBuss<L, V> {
8+
private final List<L> list = new ArrayList<>();
9+
10+
@Override
11+
public void registerListener(L listener) {
12+
this.list.add(listener);
13+
}
14+
15+
@Override
16+
public void removeListener(L listener) {
17+
this.list.remove(listener);
18+
}
19+
20+
@Override
21+
public void listen(V value) {
22+
if (SwingUtilities.isEventDispatchThread()) {
23+
for (IListener<V> listener : this.list) {
24+
listener.listen(value);
25+
}
26+
} else {
27+
SwingUtilities.invokeLater(() -> {
28+
for (IListener<V> listener : this.list) {
29+
listener.listen(value);
30+
}
31+
});
32+
}
33+
}
34+
35+
@Override
36+
public List<L> listeners() {
37+
return this.list;
38+
}
39+
}

src/main/java/com/artur114/bytecodegrab/util/ArrayListenBuss.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import javax.swing.*;
44
import java.util.ArrayList;
5-
import java.util.Collections;
65
import java.util.List;
76

87
public class ArrayListenBuss<L extends IListener<V>, V> implements IListenBuss<L, V> {
@@ -20,16 +19,8 @@ public void removeListener(L listener) {
2019

2120
@Override
2221
public void listen(V value) {
23-
if (SwingUtilities.isEventDispatchThread()) {
24-
for (IListener<V> listener : this.list) {
25-
listener.listen(value);
26-
}
27-
} else {
28-
SwingUtilities.invokeLater(() -> {
29-
for (IListener<V> listener : this.list) {
30-
listener.listen(value);
31-
}
32-
});
22+
for (IListener<V> listener : this.list) {
23+
listener.listen(value);
3324
}
3425
}
3526

src/main/java/com/artur114/bytecodegrab/util/SwingWorkerListened.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import java.util.concurrent.ExecutionException;
66

77
public abstract class SwingWorkerListened<T, V> extends SwingWorker<T, V> {
8-
private final IListenBuss<IListener<List<V>>, List<V>> processBuss = new ArrayListenBuss<>();
9-
private final IListenBuss<IListener<T>, T> doneBuss = new ArrayListenBuss<>();
8+
private final IListenBuss<IListener<List<V>>, List<V>> processBuss = new ArrayEDITListenBuss<>();
9+
private final IListenBuss<IListener<T>, T> doneBuss = new ArrayEDITListenBuss<>();
1010
private boolean disableListen = false;
1111

1212

src/main/java/com/artur114/bytecodegrab/view/CodeGrabPanel.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.artur114.bytecodegrab.jcomp.JGrabFrame;
66
import com.artur114.bytecodegrab.main.Application;
77
import com.artur114.bytecodegrab.util.*;
8+
import com.sun.tools.attach.VirtualMachineDescriptor;
89
import org.apache.logging.log4j.LogManager;
910
import org.apache.logging.log4j.Logger;
1011

@@ -13,17 +14,17 @@
1314
import javax.swing.event.DocumentListener;
1415
import javax.swing.filechooser.FileFilter;
1516
import java.awt.*;
17+
import java.awt.datatransfer.StringSelection;
1618
import java.awt.event.ActionListener;
1719
import java.awt.event.WindowAdapter;
1820
import java.awt.event.WindowEvent;
1921
import java.io.File;
20-
import java.util.Arrays;
2122
import java.util.List;
2223

2324
public class CodeGrabPanel extends JPanel {
2425
private static final Logger LOGGER = LogManager.getLogger("View/CodeGrabPanel");
25-
private final IListenBuss<IListener<IGrabStartData>, IGrabStartData> grabListenBuss = new ArrayListenBuss<>();
26-
private final IListenBuss<IListener<Void>, Void> grabAbortListenBuss = new ArrayListenBuss<>();
26+
private final IListenBuss<IListener<IGrabStartData>, IGrabStartData> grabListenBuss = new ArrayEDITListenBuss<>();
27+
private final IListenBuss<IListener<Void>, Void> grabAbortListenBuss = new ArrayEDITListenBuss<>();
2728
private JCardContainer inputCard;
2829
private JButton disconnectButton;
2930
private JButton refreshButton;
@@ -219,6 +220,16 @@ public String getDescription() {
219220
bottom.setBorder(BorderFactory.createEmptyBorder(0, 0, 1, 0));
220221
panel.add(bottom, BorderLayout.SOUTH);
221222

223+
224+
JPopupMenu popupMenu = new JPopupMenu();
225+
JMenuItem copyPid = new JMenuItem("Copy PID", Icons.iconQuad("copy.png", 16));
226+
JMenuItem copyName = new JMenuItem("Copy VM Name", Icons.iconQuad("copy.png", 16));
227+
popupMenu.add(copyPid);
228+
popupMenu.add(copyName);
229+
popupMenu.pack();
230+
231+
grabTree.setComponentPopupMenu(popupMenu);
232+
222233
return panel;
223234
}
224235

src/main/java/com/artur114/bytecodegrab/view/JvmListPanel.java

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import java.awt.event.ActionEvent;
1010
import java.awt.event.MouseAdapter;
1111
import java.awt.event.MouseEvent;
12+
import java.awt.event.MouseListener;
1213
import java.io.File;
14+
import java.util.Arrays;
1315
import java.util.Comparator;
1416
import java.util.List;
1517
import java.util.function.Consumer;
@@ -27,21 +29,41 @@ public class JvmListPanel extends JPanel {
2729
public JvmListPanel() {
2830
setLayout(new BorderLayout());
2931
this.listModel = new DefaultListModel<>();
30-
this.jvmList = new JList<>(this.listModel);
32+
this.jvmList = new JList<VirtualMachineDescriptor>(this.listModel) {
33+
private JPopupMenu popup = null;
3134

32-
this.jvmList.setCellRenderer(new JvmListCellRenderer());
35+
@Override
36+
public void setComponentPopupMenu(JPopupMenu popup) {
37+
this.popup = popup;
38+
}
3339

34-
this.jvmList.addMouseListener(new MouseAdapter() {
3540
@Override
36-
public void mousePressed(MouseEvent e) {
37-
if (SwingUtilities.isRightMouseButton(e)) {
38-
int index = jvmList.locationToIndex(e.getPoint());
39-
if (index != -1 && !jvmList.isSelectedIndex(index)) {
40-
jvmList.setSelectedIndex(index);
41+
protected void processMouseEvent(MouseEvent e) {
42+
if (!this.isEnabled()) {
43+
return;
44+
}
45+
Rectangle r = this.getCellBounds(0, this.getLastVisibleIndex());
46+
boolean outOfBounds = !r.contains(e.getPoint());
47+
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
48+
if (outOfBounds) {
49+
this.clearSelection();
50+
this.getParent().requestFocusInWindow();
51+
} else {
52+
this.requestFocusInWindow();
53+
this.setSelectedIndex(this.locationToIndex(e.getPoint()));
54+
}
55+
}
56+
if (this.popup != null && !outOfBounds && e.isPopupTrigger()) {
57+
if (SwingUtilities.isRightMouseButton(e)) {
58+
this.popup.show(this, e.getX(), e.getY());
4159
}
4260
}
4361
}
44-
});
62+
@Override
63+
protected void processMouseMotionEvent(MouseEvent e) {}
64+
};
65+
66+
this.jvmList.setCellRenderer(new JvmListCellRenderer());
4567

4668
JPanel top = new JPanel(new BorderLayout());
4769
JPanel panelB = new JPanel(new BorderLayout());

0 commit comments

Comments
 (0)