Merge pull request #261 from hopana/file_remove_support
1. add feature: context menu (remove|expand|collapse) support 2.fixbug: Issue 260
This commit is contained in:
		
						commit
						7e6e0424aa
					
				
					 2 changed files with 181 additions and 56 deletions
				
			
		| 
						 | 
				
			
			@ -1,50 +1,25 @@
 | 
			
		|||
package the.bytecode.club.bytecodeviewer.gui;
 | 
			
		||||
 | 
			
		||||
import java.awt.BorderLayout;
 | 
			
		||||
import java.awt.font.FontRenderContext;
 | 
			
		||||
import java.awt.geom.*;
 | 
			
		||||
import java.awt.Color;
 | 
			
		||||
import java.awt.Component;
 | 
			
		||||
import java.awt.Font;
 | 
			
		||||
import java.awt.Graphics;
 | 
			
		||||
import java.awt.Graphics2D;
 | 
			
		||||
import java.awt.event.ActionEvent;
 | 
			
		||||
import java.awt.event.ActionListener;
 | 
			
		||||
import java.awt.event.FocusEvent;
 | 
			
		||||
import java.awt.event.FocusListener;
 | 
			
		||||
import java.awt.event.KeyAdapter;
 | 
			
		||||
import java.awt.event.KeyEvent;
 | 
			
		||||
import java.awt.event.KeyListener;
 | 
			
		||||
import java.awt.event.MouseAdapter;
 | 
			
		||||
import java.awt.event.MouseEvent;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
 | 
			
		||||
import javax.swing.JButton;
 | 
			
		||||
import javax.swing.JCheckBox;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
import javax.swing.JScrollPane;
 | 
			
		||||
import javax.swing.JTextField;
 | 
			
		||||
import javax.swing.JTree;
 | 
			
		||||
import javax.swing.event.TreeSelectionEvent;
 | 
			
		||||
import javax.swing.event.TreeSelectionListener;
 | 
			
		||||
import javax.swing.tree.DefaultMutableTreeNode;
 | 
			
		||||
import javax.swing.tree.DefaultTreeCellRenderer;
 | 
			
		||||
import javax.swing.tree.MutableTreeNode;
 | 
			
		||||
import javax.swing.tree.TreeNode;
 | 
			
		||||
import javax.swing.tree.TreePath;
 | 
			
		||||
 | 
			
		||||
import com.sun.java.swing.plaf.windows.WindowsTreeUI;
 | 
			
		||||
import org.objectweb.asm.tree.ClassNode;
 | 
			
		||||
 | 
			
		||||
import the.bytecode.club.bytecodeviewer.*;
 | 
			
		||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
 | 
			
		||||
import the.bytecode.club.bytecodeviewer.Resources;
 | 
			
		||||
import the.bytecode.club.bytecodeviewer.util.FileChangeNotifier;
 | 
			
		||||
import the.bytecode.club.bytecodeviewer.util.FileContainer;
 | 
			
		||||
import the.bytecode.club.bytecodeviewer.util.FileDrop;
 | 
			
		||||
import the.bytecode.club.bytecodeviewer.util.LazyNameUtil;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
import javax.swing.event.TreeSelectionEvent;
 | 
			
		||||
import javax.swing.event.TreeSelectionListener;
 | 
			
		||||
import javax.swing.tree.*;
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.awt.event.*;
 | 
			
		||||
import java.awt.font.FontRenderContext;
 | 
			
		||||
import java.awt.geom.Rectangle2D;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
 * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite        *
 | 
			
		||||
| 
						 | 
				
			
			@ -195,6 +170,60 @@ public class FileNavigationPane extends VisibleComponent implements
 | 
			
		|||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void showPopMenu(MyTree tree, TreePath selPath, int x, int y) {
 | 
			
		||||
        if (selPath == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final JPopupMenu pop = new JPopupMenu();
 | 
			
		||||
        pop.add(new AbstractAction("Remove") {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void actionPerformed(ActionEvent e) {
 | 
			
		||||
                TreePath selPath = FileNavigationPane.this.tree.getPathForLocation(x, y);
 | 
			
		||||
                DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode) selPath.getLastPathComponent();
 | 
			
		||||
                Enumeration enumeration = treeRoot.children();
 | 
			
		||||
                while (enumeration.hasMoreElements()) {
 | 
			
		||||
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
 | 
			
		||||
                    if (node.isNodeAncestor(selectNode)) {
 | 
			
		||||
                        DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
 | 
			
		||||
                        root.remove(node);
 | 
			
		||||
                        for (FileContainer fileContainer : BytecodeViewer.files) {
 | 
			
		||||
                            if (fileContainer.name.equals(selectNode.toString())) {
 | 
			
		||||
                                removeFile(fileContainer);
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        updateTree();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        pop.add(new AbstractAction("Expand", WindowsTreeUI.ExpandedIcon.createExpandedIcon()) {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void actionPerformed(ActionEvent e) {
 | 
			
		||||
                TreePath selPath = FileNavigationPane.this.tree.getPathForLocation(x, y);
 | 
			
		||||
                expandAll(tree, selPath, true);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        pop.add(new AbstractAction("Collapse", WindowsTreeUI.CollapsedIcon.createCollapsedIcon()) {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void actionPerformed(ActionEvent e) {
 | 
			
		||||
                TreePath selPath = FileNavigationPane.this.tree.getPathForLocation(x, y);
 | 
			
		||||
                expandAll(tree, selPath, false);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        pop.show(this.tree, x, y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void removeFile(FileContainer fileContainer) {
 | 
			
		||||
        BytecodeViewer.files.remove(fileContainer);
 | 
			
		||||
        LazyNameUtil.removeName(fileContainer.name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public FileNavigationPane(final FileChangeNotifier fcn) {
 | 
			
		||||
        super("ClassNavigation");
 | 
			
		||||
        this.fcn = fcn;
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +232,30 @@ public class FileNavigationPane extends VisibleComponent implements
 | 
			
		|||
        quickSearch.setForeground(Color.gray);
 | 
			
		||||
        setTitle("Files");
 | 
			
		||||
 | 
			
		||||
        tree.addMouseListener(new MouseAdapter() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void mouseReleased(MouseEvent e) {
 | 
			
		||||
                if (e.isMetaDown()) {
 | 
			
		||||
                    MyTree tree = (MyTree) e.getSource();
 | 
			
		||||
                    TreePath selPath = FileNavigationPane.this.tree.getPathForLocation(e.getX(), e.getY());
 | 
			
		||||
                    if (selPath == null) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode) selPath.getLastPathComponent();
 | 
			
		||||
                    Enumeration enumeration = treeRoot.children();
 | 
			
		||||
                    while (enumeration.hasMoreElements()) {
 | 
			
		||||
                        DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
 | 
			
		||||
                        if (node.isNodeAncestor(selectNode)) {
 | 
			
		||||
                            // pop.show(tree, e.getX(), e.getY());
 | 
			
		||||
                            showPopMenu(tree, selPath, e.getX(), e.getY());
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.open.addActionListener(new ActionListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void actionPerformed(ActionEvent e) {
 | 
			
		||||
| 
						 | 
				
			
			@ -513,6 +566,7 @@ public class FileNavigationPane extends VisibleComponent implements
 | 
			
		|||
                return hash;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -556,8 +610,9 @@ public class FileNavigationPane extends VisibleComponent implements
 | 
			
		|||
 | 
			
		||||
    public void openPath(TreePath path)
 | 
			
		||||
    {
 | 
			
		||||
        if (path == null)
 | 
			
		||||
        if (path == null || path.getPathCount() == 1) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final StringBuilder nameBuffer = new StringBuilder();
 | 
			
		||||
        for (int i = 2; i < path.getPathCount(); i++) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ package the.bytecode.club.bytecodeviewer.util;
 | 
			
		|||
 ***************************************************************************/
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.io.FilenameUtils;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -29,31 +30,100 @@ public class LazyNameUtil
 | 
			
		|||
{
 | 
			
		||||
    public static boolean SAME_NAME_JAR_WORKSPACE = false;
 | 
			
		||||
 | 
			
		||||
    private static final HashMap<String, Integer> nameMap = new HashMap<>();
 | 
			
		||||
    private static final HashMap<String, SeqAndCount> nameMap = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public static void reset()
 | 
			
		||||
    {
 | 
			
		||||
        nameMap.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String applyNameChanges(String name)
 | 
			
		||||
    {
 | 
			
		||||
        if(nameMap.containsKey(name))
 | 
			
		||||
        {
 | 
			
		||||
            if(!SAME_NAME_JAR_WORKSPACE)
 | 
			
		||||
    public static String applyNameChanges(String name) {
 | 
			
		||||
        if (nameMap.containsKey(name)) {
 | 
			
		||||
            if (!SAME_NAME_JAR_WORKSPACE) {
 | 
			
		||||
                SAME_NAME_JAR_WORKSPACE = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int counter = nameMap.get(name)+1;
 | 
			
		||||
            nameMap.put(name, counter);
 | 
			
		||||
 | 
			
		||||
            return FilenameUtils.removeExtension(name)+"#"+counter+"."+FilenameUtils.getExtension(name);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            nameMap.put(name, 1);
 | 
			
		||||
            SeqAndCount seqAndCount = nameMap.get(name);
 | 
			
		||||
            nameMap.put(name, seqAndCount.incrSeqAndCount());
 | 
			
		||||
            return FilenameUtils.removeExtension(name) + "#" + seqAndCount.getSeq() + "." + FilenameUtils.getExtension(name);
 | 
			
		||||
        } else {
 | 
			
		||||
            nameMap.put(name, SeqAndCount.init());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void removeName(String name) {
 | 
			
		||||
        if (StringUtils.isBlank(name)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (name.contains("#")) {
 | 
			
		||||
            name = name.substring(0, name.indexOf("#")) + name.substring(name.indexOf("."));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SeqAndCount seqAndCount = nameMap.get(name);
 | 
			
		||||
        if (seqAndCount == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // sequence remain the same and decrease the count
 | 
			
		||||
        // still the count become 1
 | 
			
		||||
        if (seqAndCount.getCount() == 1) {
 | 
			
		||||
            nameMap.remove(name);
 | 
			
		||||
        } else {
 | 
			
		||||
            nameMap.put(name, seqAndCount.decrCount());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SeqAndCount {
 | 
			
		||||
    Integer seq;
 | 
			
		||||
    Integer count;
 | 
			
		||||
 | 
			
		||||
    public static SeqAndCount init() {
 | 
			
		||||
        SeqAndCount seqAndCount = new SeqAndCount();
 | 
			
		||||
        seqAndCount.setSeq(1);
 | 
			
		||||
        seqAndCount.setCount(1);
 | 
			
		||||
        return seqAndCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SeqAndCount incrSeq() {
 | 
			
		||||
        seq = seq + 1;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SeqAndCount incrCount() {
 | 
			
		||||
        count = count + 1;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SeqAndCount decrCount() {
 | 
			
		||||
        count = count - 1;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SeqAndCount incrSeqAndCount() {
 | 
			
		||||
        seq = seq + 1;
 | 
			
		||||
        count = count + 1;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Integer getSeq() {
 | 
			
		||||
        return seq;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSeq(Integer seq) {
 | 
			
		||||
        this.seq = seq;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Integer getCount() {
 | 
			
		||||
        return count;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setCount(Integer count) {
 | 
			
		||||
        this.count = count;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue