package jadex.tools.debugger; import jadex.base.SComponentFactory; import jadex.base.gui.plugin.IControlCenter; import jadex.bridge.IComponentDescription; import jadex.bridge.ICMSComponentListener; import jadex.bridge.IComponentManagementService; import jadex.bridge.IExternalAccess; import jadex.commons.IFuture; import jadex.commons.SReflect; import jadex.commons.concurrent.IResultListener; import jadex.commons.concurrent.SwingDefaultResultListener; import jadex.commons.service.SServiceProvider; import jadex.commons.service.library.ILibraryService; import jadex.tools.debugger.common.ObjectInspectorDebuggerPanel; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Collection; import java.util.Map; import java.util.StringTokenizer; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; /** * Show details of a debugged agent. */ public class DebuggerMainPanel extends JSplitPane { //-------- constants -------- /** The factory properties key for debugger panels * (value is a comma separated list of fully * qualified class names implementing IDebuggerPanel). */ public static String KEY_DEBUGGER_PANELS = "debugger.panels"; /** The model properties key for breakpoints (should contain a java.util.Collection object). */ public static String KEY_DEBUGGER_BREAKPOINTS = "debugger.breakpoints"; //-------- attributes -------- /** The control center. */ protected IControlCenter jcc; /** The component description. */ protected IComponentDescription desc; /** The step button. */ protected JButton step; /** The step button. */ protected JButton run; /** The stepmode checkbox. */ protected JCheckBox stepmode; //-------- constructors -------- /** * Create a new debugger panel. * @param container The service container. * @param comp The identifier of the component to be debugged. */ public DebuggerMainPanel(final IControlCenter jcc, final IComponentDescription desc) { super(JSplitPane.HORIZONTAL_SPLIT, new JPanel(), new JPanel()); this.jcc = jcc; this.desc = desc; this.setOneTouchExpandable(true); setDividerLocation(150); SServiceProvider.getServiceUpwards(jcc.getServiceProvider(), IComponentManagementService.class).addResultListener(new SwingDefaultResultListener(DebuggerMainPanel.this) { public void customResultAvailable(Object source, Object result) { IComponentManagementService ces = (IComponentManagementService)result; // The right panel (step & custom tabs) JPanel rightpanel = new JPanel(); setRightComponent(rightpanel); rightpanel.setLayout(new GridBagLayout()); final JTabbedPane tabs = new JTabbedPane(); IFuture ret = ces.getExternalAccess(desc.getName()); ret.addResultListener(new IResultListener() { public void resultAvailable(Object source, final Object result) { // The left panel (breakpoints) final IExternalAccess exta = (IExternalAccess)result; final BreakpointPanel[] leftpanel = new BreakpointPanel[1]; final Map props = ((IExternalAccess)result).getModel().getProperties(); SwingUtilities.invokeLater(new Runnable() { public void run() { if(props!=null && props.containsKey(KEY_DEBUGGER_BREAKPOINTS)) { Collection breakpoints = (Collection)props.get(KEY_DEBUGGER_BREAKPOINTS); leftpanel[0] = new BreakpointPanel(breakpoints, desc, jcc.getServiceProvider()); DebuggerMainPanel.this.setLeftComponent(leftpanel[0]); DebuggerMainPanel.this.setDividerLocation(150); // Hack??? } else { JPanel nobreakpoints = new JPanel(); nobreakpoints.add(new JLabel("no breakpoints")); DebuggerMainPanel.this.setLeftComponent(nobreakpoints); DebuggerMainPanel.this.setDividerLocation(0); } // Sub panels of right panel. SComponentFactory.getProperties(DebuggerMainPanel.this.jcc.getServiceProvider(), DebuggerMainPanel.this.desc.getType()) .addResultListener(new SwingDefaultResultListener(DebuggerMainPanel.this) { public void customResultAvailable(Object source, Object result) { final Map props2 = (Map)result; if(props2!=null && props2.containsKey(KEY_DEBUGGER_PANELS)) { SServiceProvider.getService(DebuggerMainPanel.this.jcc.getServiceProvider(), ILibraryService.class) .addResultListener(new SwingDefaultResultListener(DebuggerMainPanel.this) { public void customResultAvailable(Object source, Object result) { final ILibraryService libservice = (ILibraryService)result; String panels = (String)props2.get(KEY_DEBUGGER_PANELS); StringTokenizer stok = new StringTokenizer(panels, ", \t\n\r\f"); while(stok.hasMoreTokens()) { String classname = stok.nextToken(); try { Class clazz = SReflect.classForName(classname, libservice.getClassLoader()); IDebuggerPanel panel = (IDebuggerPanel)clazz.newInstance(); panel.init(DebuggerMainPanel.this.jcc, leftpanel[0], DebuggerMainPanel.this.desc.getName(), exta); tabs.addTab(panel.getTitle(), panel.getIcon(), panel.getComponent(), panel.getTooltipText()); } catch(Exception e) { e.printStackTrace(); DebuggerMainPanel.this.jcc.displayError("Error initializing debugger panel.", "Debugger panel class: "+classname, e); } } } }); } else { ObjectInspectorDebuggerPanel panel = new ObjectInspectorDebuggerPanel(); panel.init(DebuggerMainPanel.this.jcc, leftpanel[0], DebuggerMainPanel.this.desc.getName(), exta); tabs.addTab(panel.getTitle(), panel.getIcon(), panel.getComponent(), panel.getTooltipText()); } } }); } }); } public void exceptionOccurred(Object source, Exception exception) { DebuggerMainPanel.this.jcc.displayError("Error initializing debugger panels.", null, exception); } }); step = new JButton("Step"); step.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { step.setEnabled(false); run.setEnabled(false); SServiceProvider.getServiceUpwards(DebuggerMainPanel.this.jcc.getServiceProvider(), IComponentManagementService.class) .addResultListener(new SwingDefaultResultListener(DebuggerMainPanel.this) { public void customResultAvailable(Object source, Object result) { IComponentManagementService ces = (IComponentManagementService)result; IFuture ret = ces.stepComponent(DebuggerMainPanel.this.desc.getName()); ret.addResultListener(new IResultListener() { public void resultAvailable(Object source, Object result) { updatePanel((IComponentDescription)result); } public void exceptionOccurred(Object source, Exception exception) { // Hack!!! keep tool reactive in case of error!? step.setEnabled(true); run.setEnabled(true); } }); } }); } }); run = new JButton("Run"); run.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { step.setEnabled(false); run.setEnabled(false); stepmode.setSelected(false); SServiceProvider.getServiceUpwards(DebuggerMainPanel.this.jcc.getServiceProvider(), IComponentManagementService.class) .addResultListener(new SwingDefaultResultListener(DebuggerMainPanel.this) { public void customResultAvailable(Object source, Object result) { final IComponentManagementService ces = (IComponentManagementService)result; IFuture ret = ces.stepComponent(DebuggerMainPanel.this.desc.getName()); ret.addResultListener(new IResultListener() { public void resultAvailable(Object source, Object result) { IFuture ret = ces.resumeComponent(DebuggerMainPanel.this.desc.getName()); ret.addResultListener(new IResultListener() { public void resultAvailable(Object source, Object result) { updatePanel((IComponentDescription)result); } public void exceptionOccurred(Object source, Exception exception) { step.setEnabled(true); run.setEnabled(true); stepmode.setSelected(true); } }); } public void exceptionOccurred(Object source, Exception exception) { step.setEnabled(true); run.setEnabled(true); stepmode.setSelected(true); } }); } }); } }); stepmode = new JCheckBox("Step Mode"); stepmode.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SServiceProvider.getServiceUpwards(DebuggerMainPanel.this.jcc.getServiceProvider(), IComponentManagementService.class) .addResultListener(new SwingDefaultResultListener(DebuggerMainPanel.this) { public void customResultAvailable(Object source, Object result) { IComponentManagementService ces = (IComponentManagementService)result; if(stepmode.isSelected()) { ces.suspendComponent(DebuggerMainPanel.this.desc.getName()); } else { ces.resumeComponent(DebuggerMainPanel.this.desc.getName()); } } }); } }); int row = 0; int col = 0; rightpanel.add(tabs, new GridBagConstraints(col++, row, GridBagConstraints.REMAINDER, 1, 1,1, GridBagConstraints.LINE_END, GridBagConstraints.BOTH, new Insets(1,1,1,1), 0,0)); row++; col = 0; rightpanel.add(stepmode, new GridBagConstraints(col++, row, 1, 1, 1,0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(1,1,1,1), 0,0)); rightpanel.add(step, new GridBagConstraints(col++, row, 1, 1, 0,0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(1,1,1,1), 0,0)); rightpanel.add(run, new GridBagConstraints(col, row++, GridBagConstraints.REMAINDER, 1, 0,0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(1,1,1,1), 0,0)); updatePanel((IComponentDescription)desc); ces.addComponentListener(desc.getName(), new ICMSComponentListener() { public void componentChanged(IComponentDescription desc) { updatePanel(desc); } public void componentRemoved(IComponentDescription desc, Map results) { } public void componentAdded(IComponentDescription desc) { } }); } }); } /** * Dispose the panel, i.e. remove any associated resources (listeners etc.). */ public void dispose() { } protected void updatePanel(final IComponentDescription desc) { SwingUtilities.invokeLater(new Runnable() { public void run() { stepmode.setSelected(IComponentDescription.STATE_SUSPENDED.equals(desc.getState())); step.setEnabled(IComponentDescription.STATE_SUSPENDED.equals(desc.getState())); // && IComponentDescription.PROCESSINGSTATE_READY.equals(desc.getProcessingState())); run.setEnabled(IComponentDescription.STATE_SUSPENDED.equals(desc.getState())); } }); } }