From 672498dc219186e38efd769cf993f6d44e340e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Wed, 28 Dec 2011 20:17:18 +0100 Subject: [PATCH] AS3: Gui enhancement - Optimized Classes Tree (Merged clone 65403456bfea by Paolo Cancedda) --- .../jpexs/asdec/abc/gui/ClassesListTree.java | 107 +++++------ .../asdec/abc/gui/ClassesListTreeModel.java | 114 ++++++------ trunk/src/com/jpexs/asdec/abc/gui/Tree.java | 50 ++++++ .../com/jpexs/asdec/abc/gui/TreeElement.java | 168 ++++++++++++++++++ .../src/com/jpexs/asdec/abc/gui/TreePart.java | 70 -------- .../com/jpexs/asdec/abc/gui/TreeVisitor.java | 23 +++ 6 files changed, 340 insertions(+), 192 deletions(-) create mode 100644 trunk/src/com/jpexs/asdec/abc/gui/Tree.java create mode 100644 trunk/src/com/jpexs/asdec/abc/gui/TreeElement.java delete mode 100644 trunk/src/com/jpexs/asdec/abc/gui/TreePart.java create mode 100644 trunk/src/com/jpexs/asdec/abc/gui/TreeVisitor.java diff --git a/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTree.java b/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTree.java index 636a41d3d..c9a685458 100644 --- a/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTree.java +++ b/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTree.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 JPEXS + * Copyright (C) 2010-2011 JPEXS, Paolo Cancedda * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,6 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + package com.jpexs.asdec.abc.gui; import com.jpexs.asdec.Main; @@ -29,72 +30,52 @@ import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreePath; public class ClassesListTree extends JTree implements TreeSelectionListener { + public ABC abc; - public ABC abc; - - public void selectClass(int classIndex) { - List pathList = new ArrayList(); - String packageName = abc.instance_info[classIndex].getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); - String className = abc.instance_info[classIndex].getName(abc.constants).getName(abc.constants); - String full = packageName + "." + className; - String parts[] = full.split("\\."); - String s = ""; - pathList.add(new TreePart("", "", -1)); - for (int j = 0; j < parts.length; j++) { - if (!s.endsWith(".")) { - s += "."; - } - s += parts[j]; - TreePart tp = new TreePart(s, parts[j], j < parts.length - 1 ? -1 : classIndex); - if (!pathList.contains(tp)) { - pathList.add(tp); - } - } - - TreePath tp = new TreePath(pathList.toArray()); - setSelectionPath(tp); - scrollPathToVisible(tp); + public void selectClass(int classIndex) { + ClassesListTreeModel model=(ClassesListTreeModel)getModel(); + TreeElement selectedElement=model.getElementByClassIndex(classIndex); + TreePath treePath=selectedElement.getTreePath(); + setSelectionPath(treePath); + scrollPathToVisible(treePath); } - public ClassesListTree(ABC abc) { - this.abc = abc; - setModel(new ClassesListTreeModel(abc)); - addTreeSelectionListener(this); - DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer(); - ClassLoader cldr = this.getClass().getClassLoader(); - java.net.URL imageURL = cldr.getResource("com/jpexs/asdec/abc/gui/graphics/class.png"); - ImageIcon leafIcon = new ImageIcon(imageURL); - treeRenderer.setLeafIcon(leafIcon); - setCellRenderer(treeRenderer); - } + public ClassesListTree(ABC abc) { + this.abc = abc; + setModel(new ClassesListTreeModel(abc)); + addTreeSelectionListener(this); + DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer(); + ClassLoader cldr = this.getClass().getClassLoader(); + java.net.URL imageURL = cldr.getResource("com/jpexs/asdec/abc/gui/graphics/class.png"); + ImageIcon leafIcon = new ImageIcon(imageURL); + treeRenderer.setLeafIcon(leafIcon); + setCellRenderer(treeRenderer); + } - public void setABC(ABC abc) { - setModel(new ClassesListTreeModel(abc)); - this.abc = abc; - } + public void setABC(ABC abc) { + setModel(new ClassesListTreeModel(abc)); + this.abc = abc; + } - public void valueChanged(TreeSelectionEvent e) { - if (Main.isWorking()) { - return; - } - final TreePart tp = (TreePart) getLastSelectedPathComponent(); - if (tp == null) { - return; - } - if (tp.classIndex != -1) { - if (!Main.isWorking()) { - Main.startWork("Decompiling class..."); - (new Thread() { + public void valueChanged(TreeSelectionEvent e) { + if (Main.isWorking()) return; + final TreeElement tp = (TreeElement) getLastSelectedPathComponent(); + if (tp == null) return; + final int classIndex = tp.getClassIndex(); + if (classIndex != -1) { + if (!Main.isWorking()) { + Main.startWork("Decompiling class..."); + (new Thread() { - @Override - public void run() { - Main.abcMainFrame.navigator.setClassIndex(tp.classIndex); - Main.abcMainFrame.decompiledTextArea.setClassIndex(tp.classIndex, abc); - Main.abcMainFrame.detailPanel.methodTraitPanel.methodCodePanel.sourceTextArea.setText(""); - Main.stopWork(); - } - }).start(); - } - } - } + @Override + public void run() { + Main.abcMainFrame.navigator.setClassIndex(classIndex); + Main.abcMainFrame.decompiledTextArea.setClassIndex(classIndex, abc); + Main.abcMainFrame.detailPanel.methodTraitPanel.methodCodePanel.sourceTextArea.setText(""); + Main.stopWork(); + } + }).start(); + } + } + } } diff --git a/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTreeModel.java b/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTreeModel.java index 63c99e176..1f152fd63 100644 --- a/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTreeModel.java +++ b/trunk/src/com/jpexs/asdec/abc/gui/ClassesListTreeModel.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 JPEXS + * Copyright (C) 2010-2011 JPEXS, Paolo Cancedda * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,9 +29,35 @@ import java.util.List; import java.util.regex.Pattern; + +class ClassIndexVisitor implements TreeVisitor{ + + private TreeElement found=null; + private int classIndex; + public ClassIndexVisitor(int classIndex){ + this.classIndex=classIndex; + } + + public void onBranch(TreeElement branch) { + if(branch.getClassIndex()==classIndex){ + found=branch; + } + } + + public void onLeaf(TreeElement leaf) { + if(leaf.getClassIndex()==classIndex){ + found=leaf; + } + } + public TreeElement getFound(){ + return found; + } + +} + public class ClassesListTreeModel implements TreeModel { - private ABC abc; - private List pathList = new ArrayList(); + private ABC abc; + private Tree classTree = new Tree(); public ClassesListTreeModel(ABC abc) { this.abc = abc; @@ -39,65 +65,42 @@ public class ClassesListTreeModel implements TreeModel { String packageName = abc.instance_info[i].getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); String className = abc.instance_info[i].getName(abc.constants).getName(abc.constants); String full = packageName + "." + className; - String parts[] = full.split("\\."); - String s = ""; - for (int j = 0; j < parts.length; j++) { - if (!s.endsWith(".")) s += "."; - s += parts[j]; - TreePart tp = new TreePart(s, parts[j], j < parts.length - 1 ? -1 : i); - if (!pathList.contains(tp)) { - pathList.add(tp); - } - } + classTree.add(className, packageName, i); } - for (int k1 = 0; k1 < pathList.size(); k1++) { - TreePart tp1 = pathList.get(k1); - for (int k2 = 0; k2 < pathList.size(); k2++) { - if (k1 == k2) continue; - TreePart tp2 = pathList.get(k2); - if (!tp1.path.equals(tp2.path)) { - if (tp1.path.startsWith(tp2.path + ".")) { - tp2.hasSubParts = true; - } - if (tp2.path.startsWith(tp1.path + ".")) { - tp1.hasSubParts = true; - } - } - } - } - Collections.sort(pathList); } + public int getClassIndexByPath(String fullPath){ + TreeElement elem=classTree.get(fullPath); + if(elem==null){ + return -1; + } + return elem.getClassIndex(); + } + + public TreeElement getElementByClassIndex(int classIndex){ + ClassIndexVisitor civ=new ClassIndexVisitor(classIndex); + classTree.visit(civ); + return civ.getFound(); + } public Object getRoot() { - return new TreePart("", "", -1); + return classTree.getRoot(); } public Object getChild(Object parent, int index) { - int i = -1; - for (TreePart tp : pathList) { - if (tp.path.matches(Pattern.quote(((TreePart) parent).path) + "\\.[^\\.]+")) { - i++; - if (i == index) { - return tp; - } - } - } - return null; + TreeElement pte = (TreeElement)parent; + TreeElement te = pte.getChild(index); + return te; } - public int getChildCount(Object parent) { - int i = 0; - for (TreePart tp : pathList) { - if (tp.path.matches(Pattern.quote(((TreePart) parent).path) + "\\.[^\\.]+")) { - i++; - } - } - return i; + public int getChildCount(Object parent) { + TreeElement te = (TreeElement)parent; + return te.getChildCount(); } public boolean isLeaf(Object node) { - return getChildCount(node) == 0; + TreeElement te = (TreeElement)node; + return te.isLeaf(); } public void valueForPathChanged(TreePath path, Object newValue) { @@ -105,16 +108,9 @@ public class ClassesListTreeModel implements TreeModel { } public int getIndexOfChild(Object parent, Object child) { - int i = -1; - for (TreePart tp : pathList) { - if (tp.path.matches(Pattern.quote(((TreePart) parent).path) + "\\.[^\\.]+")) { - i++; - if (tp.equals(child)) { - return i; - } - } - } - return i; + TreeElement te1 = (TreeElement)parent; + TreeElement te2 = (TreeElement)child; + return te1.getIndexOfChild(te2); } public void addTreeModelListener(TreeModelListener l) { diff --git a/trunk/src/com/jpexs/asdec/abc/gui/Tree.java b/trunk/src/com/jpexs/asdec/abc/gui/Tree.java new file mode 100644 index 000000000..2b8363eae --- /dev/null +++ b/trunk/src/com/jpexs/asdec/abc/gui/Tree.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 Paolo Cancedda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +package com.jpexs.asdec.abc.gui; + +import java.util.StringTokenizer; + +public class Tree { + private final TreeElement ROOT = new TreeElement("", "", -1, null); + + public void add(String name, String path, int classIndex) { + StringTokenizer st = new StringTokenizer(path, "."); + TreeElement parent = ROOT; + while (st.hasMoreTokens()) { + String pathElement = st.nextToken(); + parent = parent.getBranch(pathElement); + } + parent.addLeaf(name, classIndex); + } + + public TreeElement getRoot() { + return ROOT; + } + + public void visit(TreeVisitor visitor) { + ROOT.visitLeafs(visitor); + ROOT.visitBranches(visitor); + } + + public TreeElement get(String fullPath) { + if ("".equals(fullPath)) { + return ROOT; + } + return ROOT.getByPath(fullPath); + } +} diff --git a/trunk/src/com/jpexs/asdec/abc/gui/TreeElement.java b/trunk/src/com/jpexs/asdec/abc/gui/TreeElement.java new file mode 100644 index 000000000..bc385d435 --- /dev/null +++ b/trunk/src/com/jpexs/asdec/abc/gui/TreeElement.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2011 Paolo Cancedda, JPEXS + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +package com.jpexs.asdec.abc.gui; + +import java.util.*; +import javax.swing.tree.TreePath; + +public class TreeElement { + private SortedMap branches; + private SortedMap leafs; + private String name; + private String path; + private int classIndex; + private TreeElement parent; + + public TreeElement(String name, String path, int classIndex, TreeElement parent) { + this.name = name; + this.path = path; + this.classIndex = classIndex; + this.parent = parent; + branches = new TreeMap(); + leafs = new TreeMap(); + } + + public TreeElement getParent() { + return parent; + } + + public String getName() { + return name; + } + + public String getPath() { + return path; + } + + public TreePath getTreePath() { + List pathList = new ArrayList(); + TreeElement temp=this; + do{ + pathList.add(0,temp); + } + while((temp=temp.getParent())!=null); + return new TreePath(pathList.toArray()); + } + + public int getClassIndex() { + return classIndex; + } + + @Override + public String toString() { + return name; + } + + TreeElement getBranch(String pathElement) { + TreeElement branch = branches.get(pathElement); + if (branch == null) { + branch = new TreeElement(pathElement, path+"."+pathElement, -1, this); + branches.put(pathElement, branch); + } + return branch; + } + + void addLeaf(String pathElement, int classIndex) { + TreeElement child = new TreeElement(pathElement, path+"."+pathElement, classIndex, this); + leafs.put(pathElement, child); + } + + public TreeElement getChild(int index) { + Iterator iter; + int startingIndex; + if (index < branches.size()) { + iter = branches.values().iterator(); + startingIndex = 0; + } else { + iter = leafs.values().iterator(); + startingIndex = branches.size(); + } + int ii = startingIndex; + TreeElement child = null; + while (ii <= index && iter.hasNext()) { + child = iter.next(); + ii++; + } + return child; + } + + public int getChildCount() { + return branches.size() + leafs.size(); + } + + public boolean isLeaf() { + return getChildCount() == 0; + } + + public int getIndexOfChild(TreeElement child) { + if (getChildCount() < 1) { + return -1; + } + Iterator iter = branches.values().iterator(); + int ii = 0; + TreeElement aChild = null; + while (aChild != child && iter.hasNext()) { + aChild = iter.next(); + if (aChild == child) { + return ii; + } + ii++; + } + iter = leafs.values().iterator(); + while (aChild != child && iter.hasNext()) { + aChild = iter.next(); + if (aChild == child) { + return ii; + } + ii++; + } + return -1; + } + + void visitBranches(TreeVisitor visitor) { + Iterator iter = branches.values().iterator(); + while (iter.hasNext()) { + TreeElement branch = iter.next(); + visitor.onBranch(branch); + branch.visitLeafs(visitor); + branch.visitBranches(visitor); + } + } + + void visitLeafs(TreeVisitor visitor) { + Iterator iter = leafs.values().iterator(); + while (iter.hasNext()) { + TreeElement leaf = iter.next(); + visitor.onLeaf(leaf); + } + } + + TreeElement getByPath(String fullPath) { + TreeElement te = this; + StringTokenizer st = new StringTokenizer(fullPath, "."); + while (st.hasMoreTokens()) { + String pathElement = st.nextToken(); + TreeElement nte = te.branches.get(pathElement); + if (nte == null) { + nte = te.leafs.get(pathElement); + } + te = nte; + } + return te; + } +} diff --git a/trunk/src/com/jpexs/asdec/abc/gui/TreePart.java b/trunk/src/com/jpexs/asdec/abc/gui/TreePart.java deleted file mode 100644 index 678490dcc..000000000 --- a/trunk/src/com/jpexs/asdec/abc/gui/TreePart.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010-2011 JPEXS - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -package com.jpexs.asdec.abc.gui; - - -public class TreePart implements Comparable { - - public String path; - public String name; - public int classIndex; - public boolean hasSubParts = false; - - public TreePart(String path, String name, int classIndex) { - this.path = path; - this.name = name; - this.classIndex = classIndex; - } - - @Override - public String toString() { - return name; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final TreePart other = (TreePart) obj; - if ((this.path == null) ? (other.path != null) : !this.path.equals(other.path)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 23 * hash + (this.path != null ? this.path.hashCode() : 0); - return hash; - } - - public int compareTo(Object o) { - if (o instanceof TreePart) { - if (((TreePart) o).hasSubParts && (!hasSubParts)) return 1; - if ((!((TreePart) o).hasSubParts) && (hasSubParts)) return -1; - return (path + "." + name).compareTo(((TreePart) o).path + "." + ((TreePart) o).name); - } - return -1; - } -} diff --git a/trunk/src/com/jpexs/asdec/abc/gui/TreeVisitor.java b/trunk/src/com/jpexs/asdec/abc/gui/TreeVisitor.java new file mode 100644 index 000000000..a61dd2f9f --- /dev/null +++ b/trunk/src/com/jpexs/asdec/abc/gui/TreeVisitor.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2011 Paolo Cancedda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +package com.jpexs.asdec.abc.gui; + +public interface TreeVisitor { + public void onBranch(TreeElement branch); + public void onLeaf(TreeElement leaf); +}