mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-15 21:48:12 +00:00
Debugger - display variables in the tree structure
Set variables while debugging
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -65,4 +65,7 @@ hs_err_pid*.log
|
||||
/libsrc/cmykjpeg/nbproject/private/
|
||||
/libsrc/Plugins/nbproject/private/
|
||||
/libsrc/Plugins/build/
|
||||
/libsrc/Plugins/dist/
|
||||
/libsrc/Plugins/dist/
|
||||
/libsrc/treetable/nbproject/private/
|
||||
/libsrc/treetable/build/
|
||||
/libsrc/treetable/dist/
|
||||
Binary file not shown.
BIN
lib/treetable.jar
Normal file
BIN
lib/treetable.jar
Normal file
Binary file not shown.
@@ -191,7 +191,12 @@ is divided into following sections:
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="javac.fork" value="${jdkBug6558476}"/>
|
||||
<condition else="false" property="javac.fork">
|
||||
<or>
|
||||
<istrue value="${jdkBug6558476}"/>
|
||||
<istrue value="${javac.external.vm}"/>
|
||||
</or>
|
||||
</condition>
|
||||
<property name="jar.index" value="false"/>
|
||||
<property name="jar.index.metainf" value="${jar.index}"/>
|
||||
<property name="copylibs.rebase" value="true"/>
|
||||
@@ -217,6 +222,7 @@ is divided into following sections:
|
||||
<condition else="" property="testng.debug.mode" value="-mixed">
|
||||
<istrue value="${junit+testng.available}"/>
|
||||
</condition>
|
||||
<property name="java.failonerror" value="true"/>
|
||||
</target>
|
||||
<target name="-post-init">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
@@ -693,7 +699,7 @@ is divided into following sections:
|
||||
<sequential>
|
||||
<property environment="env"/>
|
||||
<resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
|
||||
<java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">
|
||||
<java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg value="${profiler.info.jvmargs.agent}"/>
|
||||
<jvmarg line="${profiler.info.jvmargs}"/>
|
||||
@@ -768,7 +774,7 @@ is divided into following sections:
|
||||
<attribute default="${debug.classpath}" name="classpath"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||
<java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg line="${debug-args-line}"/>
|
||||
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
|
||||
@@ -795,7 +801,7 @@ is divided into following sections:
|
||||
<attribute default="jvm" name="jvm"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||
<java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
|
||||
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
|
||||
|
||||
@@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=8064a381@1.75.2.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=73f9688e
|
||||
nbproject/build-impl.xml.script.CRC32=de1179e8
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48
|
||||
nbproject/build-impl.xml.script.CRC32=ce0b030d
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
|
||||
|
||||
@@ -189,7 +189,12 @@ is divided into following sections:
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="javac.fork" value="${jdkBug6558476}"/>
|
||||
<condition else="false" property="javac.fork">
|
||||
<or>
|
||||
<istrue value="${jdkBug6558476}"/>
|
||||
<istrue value="${javac.external.vm}"/>
|
||||
</or>
|
||||
</condition>
|
||||
<property name="jar.index" value="false"/>
|
||||
<property name="jar.index.metainf" value="${jar.index}"/>
|
||||
<property name="copylibs.rebase" value="true"/>
|
||||
@@ -215,6 +220,7 @@ is divided into following sections:
|
||||
<condition else="" property="testng.debug.mode" value="-mixed">
|
||||
<istrue value="${junit+testng.available}"/>
|
||||
</condition>
|
||||
<property name="java.failonerror" value="true"/>
|
||||
</target>
|
||||
<target name="-post-init">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
@@ -680,7 +686,7 @@ is divided into following sections:
|
||||
<sequential>
|
||||
<property environment="env"/>
|
||||
<resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
|
||||
<java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">
|
||||
<java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg value="${profiler.info.jvmargs.agent}"/>
|
||||
<jvmarg line="${profiler.info.jvmargs}"/>
|
||||
@@ -755,7 +761,7 @@ is divided into following sections:
|
||||
<attribute default="${debug.classpath}" name="classpath"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||
<java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg line="${debug-args-line}"/>
|
||||
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
|
||||
@@ -782,7 +788,7 @@ is divided into following sections:
|
||||
<attribute default="jvm" name="jvm"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||
<java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
|
||||
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
|
||||
|
||||
@@ -4,5 +4,5 @@ nbbuild.xml.stylesheet.CRC32=8064a381@1.74.2.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=0a5363c8
|
||||
nbproject/build-impl.xml.script.CRC32=13f57099
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.2.48
|
||||
nbproject/build-impl.xml.script.CRC32=6f75ce45
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
|
||||
|
||||
73
libsrc/treetable/build.xml
Normal file
73
libsrc/treetable/build.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="treetable" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project treetable.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="treetable-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
3
libsrc/treetable/manifest.mf
Normal file
3
libsrc/treetable/manifest.mf
Normal file
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
||||
1419
libsrc/treetable/nbproject/build-impl.xml
Normal file
1419
libsrc/treetable/nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
libsrc/treetable/nbproject/genfiles.properties
Normal file
8
libsrc/treetable/nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=3ded4556
|
||||
build.xml.script.CRC32=4673fb60
|
||||
build.xml.stylesheet.CRC32=8064a381@1.75.2.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=3ded4556
|
||||
nbproject/build-impl.xml.script.CRC32=646636b1
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
|
||||
73
libsrc/treetable/nbproject/project.properties
Normal file
73
libsrc/treetable/nbproject/project.properties
Normal file
@@ -0,0 +1,73 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processor.options=
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/treetable.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.8
|
||||
javac.target=1.8
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
main.class=de.hameister.treetable.TreeTableMain
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
15
libsrc/treetable/nbproject/project.xml
Normal file
15
libsrc/treetable/nbproject/project.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>treetable</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
@@ -0,0 +1,91 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
public abstract class MyAbstractTreeTableModel implements MyTreeTableModel {
|
||||
|
||||
protected Object root;
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
private static final int CHANGED = 0;
|
||||
private static final int INSERTED = 1;
|
||||
private static final int REMOVED = 2;
|
||||
private static final int STRUCTURE_CHANGED = 3;
|
||||
|
||||
public MyAbstractTreeTableModel(Object root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public Object getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public boolean isLeaf(Object node) {
|
||||
return getChildCount(node) == 0;
|
||||
}
|
||||
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Methode wird normalerweise nicht aufgerufen.
|
||||
*/
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void addTreeModelListener(TreeModelListener l) {
|
||||
listenerList.add(TreeModelListener.class, l);
|
||||
}
|
||||
|
||||
public void removeTreeModelListener(TreeModelListener l) {
|
||||
listenerList.remove(TreeModelListener.class, l);
|
||||
}
|
||||
|
||||
private void fireTreeNode(int changeType, Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == TreeModelListener.class) {
|
||||
|
||||
switch (changeType) {
|
||||
case CHANGED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesChanged(e);
|
||||
break;
|
||||
case INSERTED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesInserted(e);
|
||||
break;
|
||||
case REMOVED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e);
|
||||
break;
|
||||
case STRUCTURE_CHANGED:
|
||||
((TreeModelListener) listeners[i + 1]).treeStructureChanged(e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(CHANGED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(INSERTED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(REMOVED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(STRUCTURE_CHANGED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
}
|
||||
64
libsrc/treetable/src/de/hameister/treetable/MyDataModel.java
Normal file
64
libsrc/treetable/src/de/hameister/treetable/MyDataModel.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class MyDataModel extends MyAbstractTreeTableModel {
|
||||
|
||||
// Spalten Name.
|
||||
|
||||
static protected String[] columnNames = {"Knotentext", "String", "Datum", "Integer"};
|
||||
|
||||
// Spalten Typen.
|
||||
static protected Class<?>[] columnTypes = {MyTreeTableModel.class, String.class, Date.class, Integer.class};
|
||||
|
||||
public MyDataModel(MyDataNode rootNode) {
|
||||
super(rootNode);
|
||||
root = rootNode;
|
||||
}
|
||||
|
||||
public Object getChild(Object parent, int index) {
|
||||
return ((MyDataNode) parent).getChildren().get(index);
|
||||
}
|
||||
|
||||
public int getChildCount(Object parent) {
|
||||
return ((MyDataNode) parent).getChildren().size();
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
public String getColumnName(int column) {
|
||||
return columnNames[column];
|
||||
}
|
||||
|
||||
public Class<?> getColumnClass(int column) {
|
||||
return columnTypes[column];
|
||||
}
|
||||
|
||||
public Object getValueAt(Object node, int column) {
|
||||
switch (column) {
|
||||
case 0:
|
||||
return ((MyDataNode) node).getName();
|
||||
case 1:
|
||||
return ((MyDataNode) node).getCapital();
|
||||
case 2:
|
||||
return ((MyDataNode) node).getDeclared();
|
||||
case 3:
|
||||
return ((MyDataNode) node).getArea();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(Object node, int column) {
|
||||
return true; // Important to activate TreeExpandListener
|
||||
}
|
||||
|
||||
public void setValueAt(Object aValue, Object node, int column) {
|
||||
}
|
||||
|
||||
}
|
||||
56
libsrc/treetable/src/de/hameister/treetable/MyDataNode.java
Normal file
56
libsrc/treetable/src/de/hameister/treetable/MyDataNode.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class MyDataNode {
|
||||
|
||||
private String name;
|
||||
private String capital;
|
||||
private Date declared;
|
||||
private Integer area;
|
||||
|
||||
private List<MyDataNode> children;
|
||||
|
||||
public MyDataNode(String name, String capital, Date declared, Integer area, List<MyDataNode> children) {
|
||||
this.name = name;
|
||||
this.capital = capital;
|
||||
this.declared = declared;
|
||||
this.area = area;
|
||||
this.children = children;
|
||||
|
||||
if (this.children == null) {
|
||||
this.children = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getCapital() {
|
||||
return capital;
|
||||
}
|
||||
|
||||
public Date getDeclared() {
|
||||
return declared;
|
||||
}
|
||||
|
||||
public Integer getArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
public List<MyDataNode> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Knotentext vom JTree.
|
||||
*/
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
51
libsrc/treetable/src/de/hameister/treetable/MyTreeTable.java
Normal file
51
libsrc/treetable/src/de/hameister/treetable/MyTreeTable.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.plaf.basic.BasicTableUI;
|
||||
|
||||
public class MyTreeTable extends JTable {
|
||||
|
||||
private MyTreeTableCellRenderer tree;
|
||||
private MyTreeTableModel treeTableModel;
|
||||
|
||||
public MyTreeTableCellRenderer getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public MyTreeTableModel getTreeTableModel() {
|
||||
return treeTableModel;
|
||||
}
|
||||
|
||||
public void setTreeModel(MyTreeTableModel treeTableModel) {
|
||||
// JTree erstellen.
|
||||
this.treeTableModel = treeTableModel;
|
||||
tree = new MyTreeTableCellRenderer(this, treeTableModel);
|
||||
|
||||
// Modell setzen.
|
||||
super.setModel(new MyTreeTableModelAdapter(treeTableModel, tree));
|
||||
|
||||
// Gleichzeitiges Selektieren fuer Tree und Table.
|
||||
MyTreeTableSelectionModel selectionModel = new MyTreeTableSelectionModel();
|
||||
tree.setSelectionModel(selectionModel); //For the tree
|
||||
setSelectionModel(selectionModel.getListSelectionModel()); //For the table
|
||||
|
||||
// Renderer fuer den Tree.
|
||||
setDefaultRenderer(MyTreeTableModel.class, tree);
|
||||
// Editor fuer die TreeTable
|
||||
setDefaultEditor(MyTreeTableModel.class, new MyTreeTableCellEditor(tree, this));
|
||||
|
||||
// Kein Grid anzeigen.
|
||||
setShowGrid(false);
|
||||
|
||||
// Keine Abstaende.
|
||||
setIntercellSpacing(new Dimension(0, 0));
|
||||
}
|
||||
|
||||
public MyTreeTable(MyTreeTableModel treeTableModel) {
|
||||
super();
|
||||
setUI(new BasicTableUI());
|
||||
setTreeModel(treeTableModel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.EventObject;
|
||||
|
||||
import javax.swing.AbstractCellEditor;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
|
||||
public class MyTreeTableCellEditor extends AbstractCellEditor implements TableCellEditor {
|
||||
|
||||
private JTree tree;
|
||||
private JTable table;
|
||||
|
||||
public MyTreeTableCellEditor(JTree tree, JTable table) {
|
||||
this.tree = tree;
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int r, int c) {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(EventObject e) {
|
||||
if (e instanceof MouseEvent) {
|
||||
int colunm1 = 0;
|
||||
MouseEvent me = (MouseEvent) e;
|
||||
int doubleClick = 2;
|
||||
MouseEvent newME = new MouseEvent(tree, me.getID(), me.getWhen(), me.getModifiers(), me.getX() - table.getCellRect(0, colunm1, true).x, me.getY(), doubleClick, me.isPopupTrigger());
|
||||
tree.dispatchEvent(newME);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCellEditorValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.plaf.basic.BasicTableUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.tree.TreeModel;
|
||||
|
||||
public class MyTreeTableCellRenderer extends JTree implements TableCellRenderer {
|
||||
|
||||
/**
|
||||
* Die letzte Zeile, die gerendert wurde.
|
||||
*/
|
||||
protected int visibleRow;
|
||||
|
||||
private MyTreeTable treeTable;
|
||||
|
||||
public MyTreeTableCellRenderer(MyTreeTable treeTable, TreeModel model) {
|
||||
super(model);
|
||||
setUI(new BasicTreeUI());
|
||||
|
||||
this.treeTable = treeTable;
|
||||
|
||||
// Setzen der Zeilenhoehe fuer die JTable
|
||||
// Muss explizit aufgerufen werden, weil treeTable noch
|
||||
// null ist, wenn super(model) setRowHeight aufruft!
|
||||
setRowHeight(getRowHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree und Table muessen die gleiche Hoehe haben.
|
||||
*/
|
||||
public void setRowHeight(int rowHeight) {
|
||||
if (rowHeight > 0) {
|
||||
super.setRowHeight(rowHeight);
|
||||
if (treeTable != null && treeTable.getRowHeight() != rowHeight) {
|
||||
treeTable.setRowHeight(getRowHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree muss die gleiche Hoehe haben wie Table.
|
||||
*/
|
||||
public void setBounds(int x, int y, int w, int h) {
|
||||
super.setBounds(x, 0, w, treeTable.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorgt fuer die Einrueckung der Ordner.
|
||||
*/
|
||||
public void paint(Graphics g) {
|
||||
g.translate(0, -visibleRow * getRowHeight());
|
||||
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Renderer mit der passenden Hintergrundfarbe zurueck.
|
||||
*/
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
if (isSelected) {
|
||||
setBackground(table.getSelectionBackground());
|
||||
} else {
|
||||
setBackground(table.getBackground());
|
||||
}
|
||||
|
||||
visibleRow = row;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
|
||||
|
||||
import javax.swing.tree.TreeModel;
|
||||
|
||||
public interface MyTreeTableModel extends TreeModel {
|
||||
|
||||
/**
|
||||
* Returns the number of available columns.
|
||||
*
|
||||
* @return Number of Columns
|
||||
*/
|
||||
public int getColumnCount();
|
||||
|
||||
/**
|
||||
* Returns the column name.
|
||||
*
|
||||
* @param column Column number
|
||||
* @return Column name
|
||||
*/
|
||||
public String getColumnName(int column);
|
||||
|
||||
/**
|
||||
* Returns the type (class) of a column.
|
||||
*
|
||||
* @param column Column number
|
||||
* @return Class
|
||||
*/
|
||||
public Class<?> getColumnClass(int column);
|
||||
|
||||
/**
|
||||
* Returns the value of a node in a column.
|
||||
*
|
||||
* @param node Node
|
||||
* @param column Column number
|
||||
* @return Value of the node in the column
|
||||
*/
|
||||
public Object getValueAt(Object node, int column);
|
||||
|
||||
/**
|
||||
* Check if a cell of a node in one column is editable.
|
||||
*
|
||||
* @param node Node
|
||||
* @param column Column number
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean isCellEditable(Object node, int column);
|
||||
|
||||
/**
|
||||
* Sets a value for a node in one column.
|
||||
*
|
||||
* @param aValue New value
|
||||
* @param node Node
|
||||
* @param column Column number
|
||||
*/
|
||||
public void setValueAt(Object aValue, Object node, int column);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.event.TreeExpansionEvent;
|
||||
import javax.swing.event.TreeExpansionListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
public class MyTreeTableModelAdapter extends AbstractTableModel {
|
||||
|
||||
JTree tree;
|
||||
MyTreeTableModel treeTableModel;
|
||||
|
||||
public MyTreeTableModelAdapter(MyTreeTableModel treeTableModel, JTree tree) {
|
||||
this.tree = tree;
|
||||
this.treeTableModel = treeTableModel;
|
||||
|
||||
tree.addTreeExpansionListener(new TreeExpansionListener() {
|
||||
public void treeExpanded(TreeExpansionEvent event) {
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
public void treeCollapsed(TreeExpansionEvent event) {
|
||||
fireTableDataChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
return treeTableModel.getColumnCount();
|
||||
}
|
||||
|
||||
public String getColumnName(int column) {
|
||||
return treeTableModel.getColumnName(column);
|
||||
}
|
||||
|
||||
public Class<?> getColumnClass(int column) {
|
||||
return treeTableModel.getColumnClass(column);
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
return tree.getRowCount();
|
||||
}
|
||||
|
||||
protected Object nodeForRow(int row) {
|
||||
TreePath treePath = tree.getPathForRow(row);
|
||||
return treePath.getLastPathComponent();
|
||||
}
|
||||
|
||||
public Object getValueAt(int row, int column) {
|
||||
return treeTableModel.getValueAt(nodeForRow(row), column);
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return treeTableModel.isCellEditable(nodeForRow(row), column);
|
||||
}
|
||||
|
||||
public void setValueAt(Object value, int row, int column) {
|
||||
treeTableModel.setValueAt(value, nodeForRow(row), column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
|
||||
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.tree.DefaultTreeSelectionModel;
|
||||
|
||||
public class MyTreeTableSelectionModel extends DefaultTreeSelectionModel {
|
||||
|
||||
public MyTreeTableSelectionModel() {
|
||||
super();
|
||||
|
||||
getListSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ListSelectionModel getListSelectionModel() {
|
||||
return listSelectionModel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package de.hameister.treetable;
|
||||
|
||||
import java.awt.Container;
|
||||
import java.awt.GridLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
public class TreeTableMain extends JFrame {
|
||||
|
||||
public TreeTableMain() {
|
||||
super("Tree Table Demo");
|
||||
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
setLayout(new GridLayout(0, 1));
|
||||
MyAbstractTreeTableModel treeTableModel = new MyDataModel(createDataStructure());
|
||||
|
||||
MyTreeTable myTreeTable = new MyTreeTable(treeTableModel);
|
||||
|
||||
Container cPane = getContentPane();
|
||||
|
||||
cPane.add(new JScrollPane(myTreeTable));
|
||||
|
||||
setSize(1000, 800);
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
}
|
||||
|
||||
private static MyDataNode createDataStructure() {
|
||||
List<MyDataNode> children1 = new ArrayList<MyDataNode>();
|
||||
children1.add(new MyDataNode("N12", "C12", new Date(), Integer.valueOf(50), null));
|
||||
children1.add(new MyDataNode("N13", "C13", new Date(), Integer.valueOf(60), null));
|
||||
children1.add(new MyDataNode("N14", "C14", new Date(), Integer.valueOf(70), null));
|
||||
children1.add(new MyDataNode("N15", "C15", new Date(), Integer.valueOf(80), null));
|
||||
|
||||
List<MyDataNode> children2 = new ArrayList<MyDataNode>();
|
||||
children2.add(new MyDataNode("N12", "C12", new Date(), Integer.valueOf(10), null));
|
||||
children2.add(new MyDataNode("N13", "C13", new Date(), Integer.valueOf(20), children1));
|
||||
children2.add(new MyDataNode("N14", "C14", new Date(), Integer.valueOf(30), null));
|
||||
children2.add(new MyDataNode("N15", "C15", new Date(), Integer.valueOf(40), null));
|
||||
|
||||
List<MyDataNode> rootNodes = new ArrayList<MyDataNode>();
|
||||
rootNodes.add(new MyDataNode("N1", "C1", new Date(), Integer.valueOf(10), children2));
|
||||
rootNodes.add(new MyDataNode("N2", "C2", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N3", "C3", new Date(), Integer.valueOf(10), children2));
|
||||
rootNodes.add(new MyDataNode("N4", "C4", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N5", "C5", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N6", "C6", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N7", "C7", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N8", "C8", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N9", "C9", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N10", "C10", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N11", "C11", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N12", "C7", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N13", "C8", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N14", "C9", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N15", "C10", new Date(), Integer.valueOf(10), children1));
|
||||
rootNodes.add(new MyDataNode("N16", "C11", new Date(), Integer.valueOf(10), children1));
|
||||
MyDataNode root = new MyDataNode("R1", "R1", new Date(), Integer.valueOf(10), rootNodes);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static void main(final String[] args) {
|
||||
Runnable gui = new Runnable() {
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
new TreeTableMain().setVisible(true);
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(gui);
|
||||
}
|
||||
}
|
||||
@@ -308,7 +308,7 @@
|
||||
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
|
||||
<compilation-unit>
|
||||
<package-root>src</package-root>
|
||||
<classpath mode="compile">lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar;lib/flashdebugger.jar</classpath>
|
||||
<classpath mode="compile">lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar;lib/flashdebugger.jar;lib/treetable.jar</classpath>
|
||||
<built-to>build</built-to>
|
||||
<built-to>javadoc</built-to>
|
||||
<built-to>reports</built-to>
|
||||
|
||||
@@ -21,6 +21,11 @@ import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
|
||||
import de.hameister.treetable.MyAbstractTreeTableModel;
|
||||
import de.hameister.treetable.MyTreeTable;
|
||||
import de.hameister.treetable.MyTreeTableModel;
|
||||
import de.hameister.treetable.MyTreeTableModelAdapter;
|
||||
import de.hameister.treetable.MyTreeTableSelectionModel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
@@ -43,7 +48,15 @@ import javax.swing.JTable;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.plaf.basic.BasicTableUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -51,11 +64,11 @@ import javax.swing.table.DefaultTableModel;
|
||||
*/
|
||||
public class DebugPanel extends JPanel {
|
||||
|
||||
private JTable debugRegistersTable;
|
||||
private MyTreeTable debugRegistersTable;
|
||||
|
||||
private JTable debugLocalsTable;
|
||||
private MyTreeTable debugLocalsTable; //JTable debugLocalsTable;
|
||||
|
||||
private JTable debugScopeTable;
|
||||
private MyTreeTable debugScopeTable;
|
||||
|
||||
private JTable callStackTable;
|
||||
|
||||
@@ -88,10 +101,34 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
private SelectedTab selectedTab = null;
|
||||
|
||||
private void safeSetTreeModel(MyTreeTable tt, MyTreeTableModel tmodel) {
|
||||
List<List<String>> expanded = View.getExpandedNodes(tt.getTree());
|
||||
|
||||
int selRows[] = tt.getSelectedRows();
|
||||
|
||||
TreePath selPaths[] = new TreePath[selRows.length];
|
||||
for (int i = 0; i < selRows.length; i++) {
|
||||
selPaths[i] = tt.getTree().getPathForRow(selRows[i]);
|
||||
}
|
||||
tt.setTreeModel(tmodel);
|
||||
//tt.getTree().setRootVisible(false);
|
||||
|
||||
View.expandTreeNodes(tt.getTree(), expanded);
|
||||
for (int i = 0; i < selRows.length; i++) {
|
||||
selRows[i] = tt.getTree().getRowForPath(selPaths[i]);
|
||||
if (i == 0) {
|
||||
tt.setRowSelectionInterval(selRows[i], selRows[i]);
|
||||
} else {
|
||||
tt.addRowSelectionInterval(selRows[i], selRows[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DebugPanel() {
|
||||
super(new BorderLayout());
|
||||
debugRegistersTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>()));
|
||||
debugLocalsTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>()));
|
||||
debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()));
|
||||
debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>()));
|
||||
|
||||
//Add watch feature, commented out. I tried it, but without success. I can't add watch in Flash Pro or FDB either. :-(
|
||||
/*
|
||||
@@ -161,7 +198,7 @@ public class DebugPanel extends JPanel {
|
||||
debugScopeTable.addMouseListener(watchHandler);
|
||||
|
||||
*/
|
||||
debugScopeTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>()));
|
||||
debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>()));
|
||||
|
||||
callStackTable = new JTable();
|
||||
stackTable = new JTable();
|
||||
@@ -271,21 +308,56 @@ public class DebugPanel extends JPanel {
|
||||
for (int i = 0; i < f.registers.size(); i++) {
|
||||
regVarIds.add(0L);
|
||||
}
|
||||
debugRegistersTable.setModel(new ABCPanel.VariablesTableModel(f.registers, regVarIds));
|
||||
safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(debugRegistersTable, f.registers, regVarIds));
|
||||
List<Variable> locals = new ArrayList<>();
|
||||
locals.addAll(f.arguments);
|
||||
locals.addAll(f.variables);
|
||||
|
||||
List<Long> localIds = new ArrayList<>();
|
||||
localIds.addAll(f.argumentIds);
|
||||
localIds.addAll(f.variableIds);
|
||||
localIds.addAll(f.argumentFrameIds);
|
||||
localIds.addAll(f.frameIds);
|
||||
|
||||
debugLocalsTable.setModel(new ABCPanel.VariablesTableModel(locals, localIds));
|
||||
debugScopeTable.setModel(new ABCPanel.VariablesTableModel(f.scopeChain, f.scopeChainIds));
|
||||
safeSetTreeModel(debugLocalsTable, new ABCPanel.VariablesTableModel(debugLocalsTable, locals, localIds));
|
||||
safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(debugScopeTable, f.scopeChain, f.scopeChainFrameIds));
|
||||
|
||||
/*TableModelListener refreshListener = new TableModelListener() {
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
};*/
|
||||
TreeModelListener refreshListener = new TreeModelListener() {
|
||||
@Override
|
||||
public void treeNodesChanged(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesInserted(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesRemoved(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeStructureChanged(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
};
|
||||
debugLocalsTable.getTreeTableModel().addTreeModelListener(refreshListener);
|
||||
debugScopeTable.getTreeTableModel().addTreeModelListener(refreshListener);
|
||||
} else {
|
||||
debugRegistersTable.setModel(new DefaultTableModel());
|
||||
debugLocalsTable.setModel(new DefaultTableModel());
|
||||
debugScopeTable.setModel(new DefaultTableModel());
|
||||
debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()));
|
||||
debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>()));
|
||||
debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>()));
|
||||
}
|
||||
InBreakAtExt info = Main.getDebugHandler().getBreakInfo();
|
||||
if (info != null) {
|
||||
@@ -325,13 +397,13 @@ public class DebugPanel extends JPanel {
|
||||
varTabs.removeAll();
|
||||
tabTypes.clear();
|
||||
JPanel pa;
|
||||
if (debugRegistersTable.getRowCount() > 0) {
|
||||
if (debugRegistersTable.getRowCount() > 1 /*root*/) {
|
||||
tabTypes.add(SelectedTab.REGISTERS);
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new JScrollPane(debugRegistersTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.registers"), pa);
|
||||
}
|
||||
if (debugLocalsTable.getRowCount() > 0) {
|
||||
if (debugLocalsTable.getRowCount() > 1 /*root*/) {
|
||||
tabTypes.add(SelectedTab.LOCALS);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
@@ -339,7 +411,7 @@ public class DebugPanel extends JPanel {
|
||||
varTabs.addTab(AppStrings.translate("variables.header.locals"), pa);
|
||||
}
|
||||
|
||||
if (debugScopeTable.getRowCount() > 0) {
|
||||
if (debugScopeTable.getRowCount() > 1 /*root*/) {
|
||||
tabTypes.add(SelectedTab.SCOPECHAIN);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.jpexs.debugger.flash.Debugger;
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.DebuggerConnection;
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.VariableType;
|
||||
import com.jpexs.debugger.flash.messages.in.InAskBreakpoints;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAt;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
@@ -108,6 +109,40 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
return breakScriptName;
|
||||
}
|
||||
|
||||
public InGetVariable getVariable(long parentId, String varName, boolean children) {
|
||||
try {
|
||||
return commands.getVariable(parentId, varName, true, children);
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVariable(long parentId, String varName, int valueType, Object value) {
|
||||
try {
|
||||
String svalue = "";
|
||||
switch (valueType) {
|
||||
case VariableType.STRING:
|
||||
svalue = "" + value;
|
||||
break;
|
||||
case VariableType.NUMBER:
|
||||
svalue = "" + value;
|
||||
break;
|
||||
case VariableType.BOOLEAN:
|
||||
svalue = ((Boolean) value) ? "true" : "false";
|
||||
break;
|
||||
case VariableType.UNDEFINED:
|
||||
svalue = "undefined";
|
||||
break;
|
||||
case VariableType.NULL:
|
||||
svalue = "undefined";
|
||||
break;
|
||||
}
|
||||
commands.setVariable(parentId, varName, valueType, svalue);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeBreakPoint(String scriptName, int line) {
|
||||
if (isBreakpointInvalid(scriptName, line)) {
|
||||
invalidBreakPointMap.get(scriptName).remove(line);
|
||||
@@ -332,6 +367,17 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
clisteners.remove(l);
|
||||
}
|
||||
|
||||
public synchronized void refreshFrame() {
|
||||
if (!paused) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
frame = commands.getFrame(0);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized InFrame getFrame() {
|
||||
if (!paused) {
|
||||
return null;
|
||||
|
||||
@@ -519,6 +519,10 @@ public class Main {
|
||||
loadFromMemoryFrame.setVisible(true);
|
||||
}
|
||||
|
||||
public static void setVariable(long parentId, String varName, int valueType, Object value) {
|
||||
getDebugHandler().setVariable(parentId, varName, valueType, value);
|
||||
}
|
||||
|
||||
public static void setSubLimiter(boolean value) {
|
||||
if (value) {
|
||||
AVM2Code.toSourceLimit = Configuration.sublimiter.get();
|
||||
@@ -1394,7 +1398,9 @@ public class Main {
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
Main.mainFrame.getPanel().refreshBreakPoints();
|
||||
if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) {
|
||||
Main.mainFrame.getPanel().refreshBreakPoints();
|
||||
}
|
||||
}
|
||||
});
|
||||
flashDebugger.addConnectionListener(debugHandler);
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.VariableType;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetVariable;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
@@ -38,6 +41,13 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.TraitMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionScriptLexer;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ParsedSymbol;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.SymbolType;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
@@ -66,6 +76,9 @@ import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import de.hameister.treetable.MyTreeTable;
|
||||
import de.hameister.treetable.MyTreeTableModel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.FlowLayout;
|
||||
@@ -82,8 +95,13 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -101,7 +119,11 @@ import javax.swing.JTable;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import javax.swing.event.EventListenerList;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.text.Highlighter;
|
||||
@@ -263,30 +285,167 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
decompiledTextArea.clearScript();
|
||||
}
|
||||
|
||||
public static class VariablesTableModel implements TableModel {
|
||||
public static class VariableNode {
|
||||
|
||||
// DebuggerHandler.VariableChangedListener varChangeListener;
|
||||
List<TableModelListener> tableListeners = new ArrayList<>();
|
||||
public List<VariableNode> path = new ArrayList<>();
|
||||
|
||||
private List<Variable> vars;
|
||||
private List<Long> varIds;
|
||||
public Long parentId;
|
||||
public int level;
|
||||
|
||||
public List<Long> getVarIds() {
|
||||
return varIds;
|
||||
}
|
||||
public Variable thisVar;
|
||||
public Variable thisTrait;
|
||||
public long thisTraitId;
|
||||
|
||||
public List<Variable> getVars() {
|
||||
return new ArrayList<>(vars);
|
||||
}
|
||||
private List<Variable> childs;
|
||||
private List<Variable> childTraits;
|
||||
|
||||
public VariablesTableModel(List<Variable> vars, List<Long> varIds) {
|
||||
this.vars = vars;
|
||||
this.varIds = varIds;
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 53 * hash + Objects.hashCode(this.parentId);
|
||||
hash = 53 * hash + (this.thisVar == null ? 0 : Objects.hashCode(this.thisVar.name));
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return vars.size();
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final VariableNode other = (VariableNode) obj;
|
||||
if (!Objects.equals(this.parentId, other.parentId)) {
|
||||
return false;
|
||||
}
|
||||
if (this.thisVar == null && other.thisVar == null) {
|
||||
return true;
|
||||
}
|
||||
if (this.thisVar == null) {
|
||||
return false;
|
||||
}
|
||||
if (other.thisVar == null) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.thisVar.name, other.thisVar.name);
|
||||
}
|
||||
|
||||
public boolean loaded = false;
|
||||
|
||||
private static boolean isTraits(Variable v) {
|
||||
return (v.vType == VariableType.UNKNOWN && "traits".equals(v.typeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (level == 0) {
|
||||
return "root"; //TODO: localize?
|
||||
}
|
||||
return thisVar.name;
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
if (path.size() > 1) {
|
||||
path.get(path.size() - 2).reloadChildren();
|
||||
} else {
|
||||
//Main.getDebugHandler().refreshFrame();
|
||||
//InFrame fr = Main.getDebugHandler().getFrame();
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadChildren() {
|
||||
InGetVariable igv = Main.getDebugHandler().getVariable(parentId, thisVar.name, true);
|
||||
childs = new ArrayList<>();
|
||||
childTraits = new ArrayList<>();
|
||||
|
||||
Variable curTrait = null;
|
||||
|
||||
for (int i = 0; i < igv.childs.size(); i++) {
|
||||
if (!isTraits(igv.childs.get(i))) {
|
||||
childs.add(igv.childs.get(i));
|
||||
childTraits.add(curTrait);
|
||||
} else {
|
||||
curTrait = igv.childs.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureLoaded() {
|
||||
if (!loaded) {
|
||||
reloadChildren();
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public VariableNode getChildAt(int index) {
|
||||
ensureLoaded();
|
||||
Long parId = 0L;
|
||||
if (thisVar != null && thisVar.vType == VariableType.OBJECT) {
|
||||
parId = (Long) thisVar.value;
|
||||
}
|
||||
VariableNode vn = new VariableNode(level + 1, childs.get(index), parId, childTraits.get(index));
|
||||
vn.path.addAll(path);
|
||||
vn.path.add(vn);
|
||||
return vn;
|
||||
}
|
||||
|
||||
public int getChildCount() {
|
||||
ensureLoaded();
|
||||
return childs.size();
|
||||
}
|
||||
|
||||
public VariableNode(int level, Variable thisVar, Long parentId, Variable thisTrait) {
|
||||
this.parentId = parentId;
|
||||
this.thisVar = thisVar;
|
||||
this.level = level;
|
||||
this.thisTrait = thisTrait;
|
||||
}
|
||||
|
||||
public VariableNode(int level, Variable thisVar, Long parentId, Variable thisTrait, Long thisTraitId, List<Variable> vars, List<Variable> varTraits) {
|
||||
this.parentId = parentId;
|
||||
|
||||
this.thisVar = thisVar;
|
||||
|
||||
this.level = level;
|
||||
this.childs = vars;
|
||||
|
||||
this.thisTrait = thisTrait;
|
||||
|
||||
this.childTraits = varTraits;
|
||||
this.path.add(this);
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class VariablesTableModel implements MyTreeTableModel {
|
||||
|
||||
List<TableModelListener> tableListeners = new ArrayList<>();
|
||||
|
||||
VariableNode root;
|
||||
private Map<VariableNode, List<VariableNode>> nodeCache = new HashMap<>();
|
||||
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
private static final int CHANGED = 0;
|
||||
private static final int INSERTED = 1;
|
||||
private static final int REMOVED = 2;
|
||||
private static final int STRUCTURE_CHANGED = 3;
|
||||
|
||||
private MyTreeTable ttable;
|
||||
|
||||
public VariablesTableModel(MyTreeTable ttable, List<Variable> vars, List<Long> parentIds) {
|
||||
this.ttable = ttable;
|
||||
List<Variable> varTraits = new ArrayList<>();
|
||||
for (int i = 0; i < vars.size(); i++) {
|
||||
varTraits.add(null);
|
||||
}
|
||||
root = new VariableNode(0, null, 0L, null, 0L, vars, varTraits);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -310,17 +469,21 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
return MyTreeTableModel.class;
|
||||
}
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return false; //columnIndex == 2; //TODO: edit variables
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
Variable v = vars.get(rowIndex);
|
||||
public Object getValueAt(Object node, int columnIndex) {
|
||||
if (node == root) {
|
||||
if (columnIndex == 0) {
|
||||
return "root";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
Variable v = ((VariableNode) node).thisVar;
|
||||
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
@@ -335,24 +498,157 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
}
|
||||
return typeStr;
|
||||
case 2:
|
||||
return v.getValueAsStr();
|
||||
switch (v.vType) {
|
||||
case VariableType.OBJECT:
|
||||
case VariableType.MOVIECLIP:
|
||||
case VariableType.FUNCTION:
|
||||
return v.getTypeAsStr() + "(" + v.value + ")";
|
||||
case VariableType.STRING:
|
||||
return "\"" + Helper.escapeActionScriptString("" + v.value) + "\"";
|
||||
default:
|
||||
return "" + v.value;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
//Main.getDebugHandler().setVariableValue(rowIndex, "" + aValue);
|
||||
public boolean isCellEditable(Object node, int column) {
|
||||
return column == 0 || (column == 2 && node != root && ((VariableNode) node).thisVar.isPrimitive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableModelListener(TableModelListener l) {
|
||||
tableListeners.add(l);
|
||||
public void setValueAt(Object aValue, Object node, int column) {
|
||||
ActionScriptLexer lexer = new ActionScriptLexer(new StringReader("" + aValue));
|
||||
ParsedSymbol symb;
|
||||
try {
|
||||
symb = lexer.lex();
|
||||
ParsedSymbol f = lexer.yylex();
|
||||
if (f.type != SymbolType.EOF) {
|
||||
return;
|
||||
}
|
||||
} catch (IOException | ActionParseException ex) {
|
||||
return;
|
||||
}
|
||||
int valType;
|
||||
switch (symb.type) {
|
||||
case DOUBLE:
|
||||
valType = VariableType.NUMBER;
|
||||
break;
|
||||
case INTEGER:
|
||||
valType = VariableType.NUMBER;
|
||||
break;
|
||||
case NULL:
|
||||
valType = VariableType.NULL;
|
||||
break;
|
||||
case STRING:
|
||||
valType = VariableType.STRING;
|
||||
break;
|
||||
case UNDEFINED:
|
||||
valType = VariableType.UNDEFINED;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
Main.getDebugHandler().setVariable(((VariableNode) node).parentId, ((VariableNode) node).thisVar.name, valType, symb.value);
|
||||
//((VariableNode) node).refresh();
|
||||
Object path[] = new Object[((VariableNode) node).path.size()];
|
||||
for (int i = 0; i < path.length; i++) {
|
||||
path[i] = ((VariableNode) node).path.get(i);
|
||||
}
|
||||
valueForPathChanged(new TreePath(path), aValue);
|
||||
//fireTreeNodesChanged(this, path, new int[0]/*removed*/, new Object[]{node});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTableModelListener(TableModelListener l) {
|
||||
tableListeners.remove(l);
|
||||
public Object getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(Object parent, int index) {
|
||||
return ((VariableNode) parent).getChildAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
int cnt = ((VariableNode) parent).getChildCount();
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
return getChildCount(node) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
fireTreeNodesChanged(ttable, path.getParentPath().getPath(), new int[0], new Object[]{path.getLastPathComponent()});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
int cnt = getChildCount(parent);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (getChild(parent, i) == child) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener l) {
|
||||
listenerList.add(TreeModelListener.class, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener l) {
|
||||
listenerList.remove(TreeModelListener.class, l);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(CHANGED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(INSERTED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(REMOVED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(STRUCTURE_CHANGED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
private void fireTreeNode(int changeType, Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == TreeModelListener.class) {
|
||||
|
||||
switch (changeType) {
|
||||
case CHANGED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesChanged(e);
|
||||
break;
|
||||
case INSERTED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesInserted(e);
|
||||
break;
|
||||
case REMOVED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e);
|
||||
break;
|
||||
case STRUCTURE_CHANGED:
|
||||
((TreeModelListener) listeners[i + 1]).treeStructureChanged(e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,6 +946,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
int dpos = decompiledTextArea.getLocalDeclarationOfPos(pos, new Reference<>(null));
|
||||
if (dpos > -1) {
|
||||
decompiledTextArea.setCaretPosition(dpos);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -872,8 +1169,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
decompiledTextArea.gotoLine((int) ex.line);
|
||||
decompiledTextArea.markError();
|
||||
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
Logger.getLogger(ABCPanel.class
|
||||
.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user