From 5206379ece640642dc46b72dbee314b0ec9d98ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 15 Feb 2026 21:15:49 +0100 Subject: [PATCH] Improved switching sessions. Shortened hash length. --- .../decompiler/flash/gui/DebugPanel.java | 23 ++-- .../decompiler/flash/gui/DebugStackPanel.java | 109 +++++++++++++++--- .../decompiler/flash/gui/DebuggerHandler.java | 102 ++++++++++++++-- .../decompiler/flash/gui/DebuggerSession.java | 24 ++-- src/com/jpexs/decompiler/flash/gui/Main.java | 26 +++-- .../decompiler/flash/gui/abc/ABCPanel.java | 21 ++-- .../flash/gui/action/ActionPanel.java | 2 +- .../flash/gui/locales/MainFrame.properties | 3 +- 8 files changed, 241 insertions(+), 69 deletions(-) diff --git a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java index 11c78d93c..e7f911e5d 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java @@ -93,6 +93,8 @@ public class DebugPanel extends JPanel { private WeakReference currentSessionRef = null; + private boolean as3; + public static enum SelectedTab { LOG, STACK, SCOPECHAIN, LOCALS, REGISTERS, CALLSTACK, CONSTANTPOOL @@ -158,10 +160,11 @@ public class DebugPanel extends JPanel { } } - public DebugPanel() { + public DebugPanel(boolean as3) { super(new BorderLayout()); - debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>()), false); - debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>()), false); + this.as3 = as3; + debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(as3, debugRegistersTable, new ArrayList<>()), false); + debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(as3, debugLocalsTable, new ArrayList<>()), false); MouseAdapter watchHandler = new MouseAdapter() { @@ -374,7 +377,7 @@ public class DebugPanel extends JPanel { debugLocalsTable.addMouseListener(watchHandler); //debugScopeTable.addMouseListener(watchHandler); - debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>()), false); + debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(as3, debugScopeTable, new ArrayList<>()), false); constantPoolTable = new JTable(); traceLogTextarea = new JTextArea(); @@ -529,14 +532,14 @@ public class DebugPanel extends JPanel { } } - safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(debugRegistersTable, f.registers)); + safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(as3, debugRegistersTable, f.registers)); locals.addAll(f.arguments); locals.addAll(f.variables); - localsTable = new ABCPanel.VariablesTableModel(debugLocalsTable, locals); + localsTable = new ABCPanel.VariablesTableModel(as3, debugLocalsTable, locals); safeSetTreeModel(debugLocalsTable, localsTable); - safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(debugScopeTable, f.scopeChain)); + safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(as3, debugScopeTable, f.scopeChain)); /*TableModelListener refreshListener = new TableModelListener() { @Override @@ -573,9 +576,9 @@ public class DebugPanel extends JPanel { debugLocalsTable.getTreeTableModel().addTreeModelListener(refreshListener); debugScopeTable.getTreeTableModel().addTreeModelListener(refreshListener); } else { - debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>())); - debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>())); - debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>())); + debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(as3, debugRegistersTable, new ArrayList<>())); + debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(as3, debugLocalsTable, new ArrayList<>())); + debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(as3, debugScopeTable, new ArrayList<>())); } InConstantPool cpool = session == null ? null : session.getConstantPool(); if (cpool != null) { diff --git a/src/com/jpexs/decompiler/flash/gui/DebugStackPanel.java b/src/com/jpexs/decompiler/flash/gui/DebugStackPanel.java index d1ea7833f..973483efd 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebugStackPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/DebugStackPanel.java @@ -20,6 +20,7 @@ import com.jpexs.debugger.flash.messages.in.InBreakAtExt; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.treeitems.TreeItem; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.event.ActionEvent; @@ -33,6 +34,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.swing.DefaultComboBoxModel; +import javax.swing.DefaultListCellRenderer; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; @@ -48,6 +50,8 @@ import javax.swing.table.TableCellRenderer; public class DebugStackPanel extends JPanel { private JComboBox sessionComboBox = new JComboBox<>(); + private boolean sessionComboBoxCreating = false; + private int lastSessionComboBoxIndex = -1; private JTable stackTable; @@ -96,6 +100,13 @@ public class DebugStackPanel extends JPanel { clear(); } }); + + Main.getDebugHandler().addSelectionListener(new DebuggerHandler.SessionSelectionListener() { + @Override + public void sessionSelected(DebuggerSession newSession, int oldSessionId) { + refresh(newSession); + } + }); //JLabel titleLabel = new JLabel(AppStrings.translate("callStack.header"), JLabel.CENTER); setLayout(new BorderLayout()); @@ -118,10 +129,20 @@ public class DebugStackPanel extends JPanel { sessionComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + if (sessionComboBoxCreating) { + return; + } SessionItem selection = (SessionItem) sessionComboBox.getSelectedItem(); if (selection != null) { DebuggerSession session = Main.getDebugHandler().getSessionById(selection.id); - if (session != null && session != Main.getCurrentDebugSession()) { + if (session != null) { + if (!session.isPaused()) { + sessionComboBox.setSelectedIndex(lastSessionComboBoxIndex); + return; + } + lastSessionComboBoxIndex = sessionComboBox.getSelectedIndex(); + + Main.getDebugHandler().setSelectedSessionId(session.getId()); View.execInEventDispatch(new Runnable() { @Override public void run() { @@ -130,17 +151,62 @@ public class DebugStackPanel extends JPanel { }); View.execInEventDispatchLater(new Runnable() { @Override - public void run() { - gotoRow(0); + public void run() { + if (!session.isPaused()) { + List debuggedSwfs = new ArrayList<>(session.getDebuggedSwfs().values()); + gotoScriptNodeOrSwf(debuggedSwfs.get(debuggedSwfs.size() - 1)); + } else { + gotoRow(0); + } } }); } } } }); + sessionComboBox.setRenderer(new DefaultListCellRenderer() { + + @Override + public Component getListCellRendererComponent(javax.swing.JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + + Component c = super.getListCellRendererComponent( + list, value, index, isSelected, cellHasFocus); + + SessionItem item = (SessionItem) value; + if (item != null) { + DebuggerSession session = Main.getDebugHandler().getSessionById(item.id); + if (!session.isPaused()) { + c.setForeground(Color.GRAY); + c.setBackground(list.getBackground()); + } else { + c.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground()); + } + } + + return c; + } + }); + } + + private void gotoScriptNodeOrSwf(SWF swf) { + if (Main.getMainFrame().getPanel().getCurrentView() == MainPanel.VIEW_RESOURCES) { + TreeItem scriptNode = Main.getMainFrame().getPanel().tagTree.getFullModel().getScriptsNode(swf); + if (scriptNode != null) { + Main.getMainFrame().getPanel().setTagTreeSelectedNode(Main.getMainFrame().getPanel().getCurrentTree(), scriptNode); + return; + } + } + Main.getMainFrame().getPanel().setTagTreeSelectedNode(Main.getMainFrame().getPanel().getCurrentTree(), swf); } private void gotoRow(int row) { + if (stackTable.getModel().getRowCount() < 1) { + return; + } String swfHash = swfHashes[row]; String scriptName = (String) stackTable.getModel().getValueAt(row, 1); int line = (int) (Integer) stackTable.getModel().getValueAt(row, 2); @@ -149,16 +215,7 @@ public class DebugStackPanel extends JPanel { scriptName, line, classIndices[row], traitIndices[row], methodIndices[row], Main.isDebugPCode()); if (!scriptFound) { - if (Main.getMainFrame().getPanel().getCurrentView() == MainPanel.VIEW_RESOURCES) { - TreeItem scriptNode = Main.getMainFrame().getPanel().tagTree.getFullModel().getScriptsNode(swf); - if (scriptNode != null) { - scriptFound = true; - Main.getMainFrame().getPanel().setTagTreeSelectedNode(Main.getMainFrame().getPanel().getCurrentTree(), scriptNode); - } - } - if (!scriptFound) { - Main.getMainFrame().getPanel().setTagTreeSelectedNode(Main.getMainFrame().getPanel().getCurrentTree(), swf); - } + gotoScriptNodeOrSwf(swf); } DebuggerSession session = null; if (currentSessionRef != null) { @@ -178,13 +235,19 @@ public class DebugStackPanel extends JPanel { @Override public String toString() { - return AppStrings.translate("debug.session").replace("%id%", "" + id); + DebuggerSession session = Main.getDebugHandler().getSessionById(id); + if (session == null) { + return "-"; + } + return AppStrings.translate("debug.session").replace("%id%", "" + id) + (session.isPaused() ? "" : " " + AppStrings.translate("debug.session.running")); } } public void clear() { stackTable.setModel(new DefaultTableModel()); - active = false; + if (Main.getDebugHandler().getActiveSessions().isEmpty()) { + active = false; + } } public boolean isActive() { @@ -200,19 +263,22 @@ public class DebugStackPanel extends JPanel { int j = 0; for (int id : allSessions.keySet()) { DebuggerSession s = allSessions.get(id); - if (s == session) { + if (s == Main.getCurrentDebugSession()) { itemIndex = j; } model.addElement(new SessionItem(id)); j++; } + sessionComboBoxCreating = true; sessionComboBox.setModel(model); if (itemIndex > -1) { final int fItemIndex = itemIndex; View.execInEventDispatchLater(new Runnable() { @Override - public void run() { + public void run() { sessionComboBox.setSelectedIndex(fItemIndex); + lastSessionComboBoxIndex = fItemIndex; + sessionComboBoxCreating = false; } }); } @@ -237,16 +303,23 @@ public class DebugStackPanel extends JPanel { int f = info.files.get(i); String moduleName = session.moduleToString(f); String swfHash = null; + String swfName = "unknown"; if (moduleName.contains(":")) { swfHash = moduleName.substring(0, moduleName.indexOf(":")); moduleName = moduleName.substring(moduleName.indexOf(":") + 1); + SWF swf = Main.findOpenedSwfByHash(swfHash); + if (swf != null) { + swfName = swf.toString(); + } } else { List debuggedSwfs = new ArrayList<>(session.getDebuggedSwfs().values()); SWF lastSwf = debuggedSwfs.get(debuggedSwfs.size() - 1); swfHash = Main.getSwfHash(lastSwf); + swfName = lastSwf.toString(); } + newSwfHashes[i] = swfHash; - data[i][0] = swfHash == null ? "unknown" : Main.findOpenedSwfByHash(swfHash).toString(); + data[i][0] = swfName; data[i][1] = moduleName; data[i][2] = info.lines.get(i); data[i][3] = info.stacks.get(i); diff --git a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java index c7a1d1830..7541a0dcb 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java +++ b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java @@ -32,6 +32,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.WeakHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicInteger; /** * @author JPEXS @@ -40,6 +41,10 @@ public class DebuggerHandler implements DebugConnectionListener { private List sessions = Collections.synchronizedList(new ArrayList<>()); + private int selectedSessionId = -1; + + private final Object selectionLock = new Object(); + private boolean terminating = false; private Map>> allBreakPoints = new WeakHashMap<>(); @@ -91,7 +96,14 @@ public class DebuggerHandler implements DebugConnectionListener { public void doContinue(DebuggerSession session); } - private final List breakListeners = new CopyOnWriteArrayList<>(); + public static interface SessionSelectionListener { + + public void sessionSelected(DebuggerSession newSession, int oldSessionId); + } + + private final List selectionListeners = new ArrayList<>(); + + private final List breakListeners = new ArrayList<>(); private final List traceListeners = new ArrayList<>(); @@ -101,10 +113,22 @@ public class DebuggerHandler implements DebugConnectionListener { private final List connectionListeners = new ArrayList<>(); + public void addSelectionListener(DebuggerHandler.SessionSelectionListener l) { + selectionListeners.add(l); + } + + public void removeSelectionListener(DebuggerHandler.SessionSelectionListener l) { + selectionListeners.remove(l); + } + public void addBreakListener(DebuggerHandler.BreakListener l) { breakListeners.add(l); } + public void removeBreakListener(DebuggerHandler.BreakListener l) { + breakListeners.remove(l); + } + public void addFrameChangeListener(DebuggerHandler.FrameChangeListener l) { frameChangeListeners.add(l); } @@ -129,10 +153,6 @@ public class DebuggerHandler implements DebugConnectionListener { errorListeners.remove(l); } - public void removeBreakListener(DebuggerHandler.BreakListener l) { - breakListeners.remove(l); - } - public void addConnectionListener(DebuggerHandler.ConnectionListener l) { connectionListeners.add(l); } @@ -192,12 +212,12 @@ public class DebuggerHandler implements DebugConnectionListener { } } } - + DebuggerSession session = new DebuggerSession(this, con, breakpoints); sessions.add(session); } - public void sessionInited(DebuggerSession session) { + public void sessionInited(DebuggerSession session) { } @@ -226,8 +246,8 @@ public class DebuggerHandler implements DebugConnectionListener { synchronized (this) { if (terminating) { return; - } - terminating = true; + } + terminating = true; } for (DebuggerSession session : sessions) { if (session.isConnected()) { @@ -306,7 +326,7 @@ public class DebuggerHandler implements DebugConnectionListener { } return null; } - + public SWF getAnyDebuggedSwf() { List currentSessions = new ArrayList<>(sessions); for (DebuggerSession session : currentSessions) { @@ -316,7 +336,7 @@ public class DebuggerHandler implements DebugConnectionListener { } return null; } - + public Map getActiveSessions() { Map ret = new LinkedHashMap<>(); List currentSessions = new ArrayList<>(sessions); @@ -327,7 +347,7 @@ public class DebuggerHandler implements DebugConnectionListener { } return ret; } - + public DebuggerSession getSessionById(int id) { List currentSessions = new ArrayList<>(sessions); for (DebuggerSession session : currentSessions) { @@ -337,4 +357,62 @@ public class DebuggerHandler implements DebugConnectionListener { } return null; } + + public DebuggerSession getSelectedSession() { + int oldSelection; + int newSelection; + DebuggerSession ret = null; + synchronized (selectionLock) { + oldSelection = selectedSessionId; + newSelection = oldSelection; + Map activeSessions = getActiveSessions(); + if (activeSessions.isEmpty()) { + selectedSessionId = -1; + newSelection = -1; + } else { + + if (selectedSessionId == -1) { + DebuggerSession session = activeSessions.values().iterator().next(); + selectedSessionId = newSelection = session.getId(); + } + + ret = getSessionById(selectedSessionId); + if (ret == null) { + ret = activeSessions.values().iterator().next(); + selectedSessionId = ret.getId(); + newSelection = selectedSessionId; + } + } + } + + if (oldSelection != newSelection) { + for (SessionSelectionListener l : selectionListeners) { + l.sessionSelected(ret, oldSelection); + } + } + + return ret; + + } + + public boolean setSelectedSessionId(int id) { + DebuggerSession session = getSessionById(id); + if (session == null) { + return false; + } + int oldSelection; + int newSelection; + synchronized (selectionLock) { + oldSelection = selectedSessionId; + selectedSessionId = id; + newSelection = id; + } + + if (oldSelection != newSelection) { + for (SessionSelectionListener l : selectionListeners) { + l.sessionSelected(session, oldSelection); + } + } + return true; + } } diff --git a/src/com/jpexs/decompiler/flash/gui/DebuggerSession.java b/src/com/jpexs/decompiler/flash/gui/DebuggerSession.java index f8c6795c3..476d13607 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebuggerSession.java +++ b/src/com/jpexs/decompiler/flash/gui/DebuggerSession.java @@ -560,9 +560,9 @@ public class DebuggerSession { } return; } - Main.startWork(AppStrings.translate("work.halted.with").replace("%file%", userSwfName), null, true); + Main.startWork(AppStrings.translate("debug.session").replace("%id%", "" + id) + " - " + AppStrings.translate("work.halted.with").replace("%file%", userSwfName), null, true); } else { - Main.startWork(AppStrings.translate("work.breakat") + userBreakScriptName + ":" + message.line + " " + AppStrings.translate("debug.break.reason." + reason), null, true); + Main.startWork(AppStrings.translate("debug.session").replace("%id%", "" + id) + " - " + AppStrings.translate("work.breakat") + userBreakScriptName + ":" + message.line + " " + AppStrings.translate("debug.break.reason." + reason), null, true); } depth = 0; refreshFrame(); @@ -976,15 +976,17 @@ public class DebuggerSession { return breakReason; } - public synchronized void refreshFrame() { - if (!paused) { - return; - } - try { - frame = commands.getFrame(depth); - pool = commands.getConstantPool(0); - } catch (IOException ex) { - //ignore + public void refreshFrame() { + synchronized (this) { + if (!paused) { + return; + } + try { + frame = commands.getFrame(depth); + pool = commands.getConstantPool(0); + } catch (IOException ex) { + //ignore + } } for (DebuggerHandler.FrameChangeListener l : handler.getFrameChangeListeners()) { l.frameChanged(DebuggerSession.this); diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 6e9fcf33b..050567f73 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -249,6 +249,8 @@ public class Main { private static Map> hash2PreparedHash = new HashMap<>(); + private static final int HASH_LENGTH = 10; + public static SWF getDebuggedSWF() { return debuggedSWF; } @@ -363,12 +365,19 @@ public class Main { } } - public static synchronized boolean isDebugPaused() { + public static boolean isDebugPaused() { + boolean cond1; + synchronized (Main.class) { + cond1 = runProcess != null && runProcessDebug || !flashDebugger.isStopped(); + } + if (!cond1) { + return false; + } DebuggerSession session = getCurrentDebugSession(); if (session == null) { return false; } - return (runProcess != null && runProcessDebug || !flashDebugger.isStopped()) && session.isPaused(); + return cond1 && session.isPaused(); } public static synchronized boolean isDebugRunning() { @@ -736,7 +745,7 @@ public class Main { if (!hash2PreparedHash.containsKey(origHash)) { hash2PreparedHash.put(origHash, new LinkedHashSet<>()); } - String preparedHash = instrSWF.getHashSha256(); + String preparedHash = instrSWF.getHashSha256().substring(0, HASH_LENGTH); hash2PreparedHash.get(origHash).add(preparedHash); Logger.getLogger(Main.class.getName()).log(Level.FINE, "Prepared {0} as {1}", new Object[]{origHash, preparedHash}); /*if ("main".equals(swfHash)) { @@ -1113,7 +1122,7 @@ public class Main { } public static DebuggerSession getCurrentDebugSession() { - if (mainFrame == null) { + /*if (mainFrame == null) { return null; } if (mainFrame.getPanel() == null) { @@ -1123,7 +1132,9 @@ public class Main { if (currentSwf == null) { return null; } - return getDebugHandler().getSessionContainingSwf(currentSwf); + return getDebugHandler().getSessionContainingSwf(currentSwf);*/ + DebuggerSession session = getDebugHandler().getSelectedSession(); + return session; } public static void updateSession() { @@ -2921,7 +2932,7 @@ public class Main { for (int i = 0; i < array.length; ++i) { sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3)); } - return sb.toString(); + return sb.toString().substring(0, HASH_LENGTH); } catch (java.security.NoSuchAlgorithmException e) { //ignore } @@ -3182,6 +3193,7 @@ public class Main { @Override public void disconnected(DebuggerSession session) { + Main.updateSession(); if (Main.mainFrame != null) { Main.mainFrame.getMenu().updateComponents(); } @@ -4099,7 +4111,7 @@ public class Main { if (tit != null && tit.contains(":")) { return tit.substring(tit.lastIndexOf(":") + 1); } - return swf.getHashSha256(); + return swf.getHashSha256().substring(0, HASH_LENGTH); } public static void openSolEditor() { diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index edc4b934d..9e49cee7c 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -317,6 +317,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener childs; public List traits = new ArrayList<>(); + private boolean as3; @Override public int hashCode() { @@ -386,12 +387,12 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener parentPath, int level, Variable var, Long parentObjectId, Variable trait) { + public VariableNode(boolean as3, List parentPath, int level, Variable var, Long parentObjectId, Variable trait) { this.var = var; this.varInsideGetter = var; this.parentObjectId = parentObjectId; @@ -444,9 +445,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener parentPath, int level, Variable var, Long parentObjectId, Variable trait, List subvars) { + public VariableNode(boolean as3, List parentPath, int level, Variable var, Long parentObjectId, Variable trait, List subvars) { this.var = var; this.varInsideGetter = var; this.parentObjectId = parentObjectId; @@ -462,6 +464,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener vars) { + public VariablesTableModel(boolean as3, MyTreeTable ttable, List vars) { this.ttable = ttable; List childs = new ArrayList<>(); for (int i = 0; i < vars.size(); i++) { - childs.add(new VariableNode(new ArrayList<>(), 1, vars.get(i), 0L, null)); + childs.add(new VariableNode(as3, new ArrayList<>(), 1, vars.get(i), 0L, null)); } - root = new VariableNode(new ArrayList<>(), 0, null, 0L, null, childs); + root = new VariableNode(as3, new ArrayList<>(), 0, null, 0L, null, childs); } @Override @@ -1438,7 +1441,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener