22
33import com .artur114 .bytecodegrab .util .AsyncClassTreeBuilder ;
44import com .artur114 .bytecodegrab .util .Icons ;
5+ import org .slf4j .Logger ;
6+ import org .slf4j .LoggerFactory ;
57
68import javax .swing .*;
79
1719
1820public class JClassTree extends JPanel {
1921 private static final Color COLOR = new Color (239 , 239 , 239 );
22+ private static final Logger log = LoggerFactory .getLogger (JClassTree .class );
2023 private final Set <String > loadedClasses = new HashSet <>();
2124 private final DefaultTreeModel treeModel ;
2225 private AsyncClassTreeBuilder builder ;
@@ -38,38 +41,35 @@ public JClassTree() {
3841 @ Override
3942 public void mouseReleased (MouseEvent e ) {
4043 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+ int row = rowForY (tree , e .getY ());
45+ boolean outOfBounds = row == -1 ;
4446
4547 if (!outOfBounds ) {
4648 tree .requestFocusInWindow ();
47- popup .show (tree , e .getX (), e .getY ());
4849 tree .setSelectionRow (row );
50+ popup .show (tree , e .getX (), e .getY ());
4951 }
5052 }
5153 }
5254
5355 @ Override
5456 public void mouseClicked (MouseEvent e ) {
5557 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 ;
58+ int row = rowForY (tree , e .getY ());
59+ boolean outOfBounds = row == -1 ;
5960
6061 if (!outOfBounds ) {
6162 tree .requestFocusInWindow ();
62- popup .show (tree , e .getX (), e .getY ());
6363 tree .setSelectionRow (row );
64+ popup .show (tree , e .getX (), e .getY ());
6465 }
6566 }
6667 }
6768
6869 @ Override
6970 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 ;
71+ int row = rowForY (tree , e .getY ());
72+ boolean outOfBounds = row == -1 ;
7373 if (SwingUtilities .isLeftMouseButton (e )) {
7474 if (outOfBounds ) {
7575 tree .clearSelection ();
@@ -80,8 +80,8 @@ public void mousePressed(MouseEvent e) {
8080 }
8181 if (!outOfBounds && popup != null && e .isPopupTrigger () && SwingUtilities .isRightMouseButton (e )) {
8282 tree .requestFocusInWindow ();
83- popup .show (tree , e .getX (), e .getY ());
8483 tree .setSelectionRow (row );
84+ popup .show (tree , e .getX (), e .getY ());
8585 }
8686 }
8787
@@ -97,6 +97,21 @@ private Rectangle allRowsRectangle(JTree tree) {
9797 }
9898 return ret ;
9999 }
100+
101+ private int rowForY (JTree tree , int y ) {
102+ if (tree .getRowCount () <= 0 ) {
103+ return -1 ;
104+ }
105+ Rectangle ret = tree .getRowBounds (0 );
106+
107+ int row = y / ret .height ;
108+
109+ if (row > tree .getRowCount ()) {
110+ return -1 ;
111+ }
112+
113+ return row ;
114+ }
100115 });
101116
102117 JScrollPane pane = new JScrollPane (this .tree );
@@ -168,7 +183,7 @@ public AsyncClassTreeBuilder updateTree(Set<String> classNames) {
168183 }
169184
170185 public void clear () {
171- (( DefaultMutableTreeNode ) this .treeModel .getRoot ()). removeAllChildren ( );
186+ this .treeModel .setRoot ( null );
172187 this .loadedClasses .clear ();
173188 this .treeModel .reload ();
174189 }
@@ -225,6 +240,16 @@ public void expandSelected() {
225240 }
226241 }
227242
243+ public void collapseSelected () {
244+ TreePath [] paths = this .tree .getSelectionPaths ();
245+ if (paths == null ) {
246+ return ;
247+ }
248+ for (TreePath path : paths ) {
249+ this .collapseChild (path , (DefaultMutableTreeNode ) path .getLastPathComponent ());
250+ }
251+ }
252+
228253 public void expandAll () {
229254 for (int i = 0 ; i != this .tree .getRowCount (); i ++) {
230255 this .tree .expandRow (i );
@@ -240,7 +265,12 @@ public void collapseAll() {
240265 }
241266 }
242267
243- public void expandChild (TreePath path , DefaultMutableTreeNode parent ) {
268+ public boolean isSelectedClass () {
269+ TreePath [] paths = this .tree .getSelectionPaths ();
270+ return paths != null && paths .length >= 1 && ((DefaultMutableTreeNode ) paths [0 ].getLastPathComponent ()).getUserObject () instanceof ClassInfo ;
271+ }
272+
273+ private void expandChild (TreePath path , DefaultMutableTreeNode parent ) {
244274 this .tree .expandPath (path );
245275
246276 for (DefaultMutableTreeNode node : this .child (parent )) {
@@ -249,6 +279,15 @@ public void expandChild(TreePath path, DefaultMutableTreeNode parent) {
249279 }
250280 }
251281
282+ private void collapseChild (TreePath path , DefaultMutableTreeNode parent ) {
283+ for (DefaultMutableTreeNode node : this .child (parent )) {
284+ TreePath newPath = path .pathByAddingChild (node );
285+ this .collapseChild (newPath , node );
286+ }
287+
288+ this .tree .collapsePath (path );
289+ }
290+
252291 @ Override
253292 public void setComponentPopupMenu (JPopupMenu popup ) {
254293 this .popup = popup ;
0 commit comments