diff --git a/src/main/java/dk/aau/cs/model/CPN/ColorType.java b/src/main/java/dk/aau/cs/model/CPN/ColorType.java index 47fcea3bf..857744f40 100644 --- a/src/main/java/dk/aau/cs/model/CPN/ColorType.java +++ b/src/main/java/dk/aau/cs/model/CPN/ColorType.java @@ -11,7 +11,7 @@ public class ColorType implements Iterable { public static final ColorType COLORTYPE_DOT = new ColorType("dot") {{addColor("dot");}}; private final Vector colors = new Vector<>(); private final String id; - private final String name; + private String name; public ColorType(String name) { this(name, name); } //id is unused. Solution for now. diff --git a/src/main/java/net/tapaal/gui/debug/Debug.kt b/src/main/java/net/tapaal/gui/debug/Debug.kt index 57008cd95..22d3c9cbc 100644 --- a/src/main/java/net/tapaal/gui/debug/Debug.kt +++ b/src/main/java/net/tapaal/gui/debug/Debug.kt @@ -52,6 +52,10 @@ object DEBUG { } }) + + add(object : AbstractAction("Inspect") { + override fun actionPerformed(e: ActionEvent) = InspectSpy().show() + }) } return debugMenu diff --git a/src/main/java/net/tapaal/gui/debug/InspectSpy.kt b/src/main/java/net/tapaal/gui/debug/InspectSpy.kt new file mode 100644 index 000000000..4bc29fb59 --- /dev/null +++ b/src/main/java/net/tapaal/gui/debug/InspectSpy.kt @@ -0,0 +1,150 @@ +package net.tapaal.gui.debug + +import dk.aau.cs.model.CPN.ColorType +import dk.aau.cs.model.CPN.ProductType +import net.tapaal.gui.petrinet.editor.ConstantsPane +import pipe.gui.TAPAALGUI +import java.awt.event.ActionEvent +import java.lang.reflect.Field +import java.util.* +import javax.swing.* +import javax.swing.tree.DefaultMutableTreeNode +import javax.swing.tree.DefaultTreeModel + +class InspectSpy : JFrame() { + + private val reloadBtn = JButton(object : AbstractAction("Reload") { + override fun actionPerformed(e: ActionEvent?) { + reload() + } + }) + + private val treeRoot = DefaultMutableTreeNode("root") + private val tree = JTree(treeRoot) + + private fun reload() { + val m = tree.model as DefaultTreeModel + treeRoot.removeAllChildren() + + val global = generateGlobal() + treeRoot.add(global) + + m.reload() + tree.expandRow(0) + } + + private fun T.getPrivateField( + field: String, + ): Any? { + //val ref = this.javaClass.getDeclaredField(field) + //val ref = this.javaClass.getField(field) + var ref: Field? = null; + + var clz: Class<*>? = this.javaClass + while (clz != null || clz != Any::class.java) { + try { + ref = clz?.getDeclaredField(field) + break + } catch (e: NoSuchFieldException) { + clz = clz?.superclass + } + } + if (ref == null) throw Exception("Field not found " + field) + + ref.isAccessible = true + return ref.get(this) + } + + private fun handleField(fields: List, o: Any, parent: DefaultMutableTreeNode) { + fields.forEach { f -> + if (f is Pair<*, *>) { + parent.add(DefaultMutableTreeNode(""+f.first + ": " + o.getPrivateField(f.first as String))) + } else if ( f is Triple<*,*,*>) { + val d = DefaultMutableTreeNode("" + f.first) + + if (f.second == "vector") { + val v = o.getPrivateField(f.first as String) as Vector<*> + v.forEach { + handleField(f.third as List, it, d) + } + } + + parent.add(d) + + } + } + } + + private fun generateGlobal(): DefaultMutableTreeNode { + val global = DefaultMutableTreeNode("Global") + + val constantsPane = TAPAALGUI.getCurrentTab().getPrivateField("constantsPanel") as ConstantsPane + + val constants = DefaultMutableTreeNode("Constants") + val constantModel = constantsPane.getPrivateField("variablesListModel") as AbstractListModel<*> + constantModel.forEach { constants.add(DefaultMutableTreeNode(it)) } + global.add(constants) + + val variables = DefaultMutableTreeNode("Variables") + val variableModel = constantsPane.getPrivateField("constantsListModel") as AbstractListModel<*> + variableModel.forEach { variables.add(DefaultMutableTreeNode(it)) } + global.add(variables) + + val colorTypes = DefaultMutableTreeNode("Color Types") + val colorTypesModel = constantsPane.getPrivateField("colorTypesListModel") as AbstractListModel<*> + colorTypesModel.forEach { + val ct = DefaultMutableTreeNode(it) + + val fields = listOf(Pair("id", "string"), Pair("name", "string"), Triple("colors", "vector", listOf(Pair("colorName", "string")))) + + handleField(fields, it, ct) + + +// if (it is ColorType) { +// val fields = listOf("id", "name") +// fields.forEach { f -> +// ct.add(DefaultMutableTreeNode(f + ": " + it.getPrivateField(f))) +// } +// val colors = DefaultMutableTreeNode("Colors") +// (it.getPrivateField("colors") as Vector<*>).forEach { +// colors.add(DefaultMutableTreeNode(it)) +// } +// ct.add(colors) +// } +// if (it is ProductType) { +// val fields = listOf("name", "constituents", "colorCache") +// fields.forEach { f -> +// ct.add(DefaultMutableTreeNode(f + ": " + it.getPrivateField(f))) +// } +// ct.add(DefaultMutableTreeNode("size: " + it.size())) +// } + + colorTypes.add(ct) + } + global.add(colorTypes) + + + + return global + } + + + init { + contentPane.layout = BoxLayout(contentPane, BoxLayout.Y_AXIS) + contentPane.add(reloadBtn) + + contentPane.add(JScrollPane(tree)) + + reload() + pack() + + } + + +} + +private fun AbstractListModel.forEach(function: (e: E)->Unit) { + for (i in 0 until this.size) { + function(this.getElementAt(i)) + } +}