/* * Copyright (C) 2012 Jason Gedge <http://www.gedge.ca> * * This file is part of the OpGraph project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package ca.gedge.opgraph.app.components; import javax.swing.JEditorPane; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.StyleSheet; import ca.gedge.opgraph.InputField; import ca.gedge.opgraph.OpContext; import ca.gedge.opgraph.OpNode; import ca.gedge.opgraph.OutputField; import ca.gedge.opgraph.Processor; /** * A component to show inputs and output values from a node's {@link OpContext}. */ public class ContextViewerPanel extends JEditorPane { /** The processing context being debugged */ private Processor processor; /** The node currently being viewed */ private OpNode node; /** * Default constructor. */ public ContextViewerPanel() { this.processor = null; this.node = null; // Set up editor kit final HTMLEditorKit kit = new HTMLEditorKit(); final StyleSheet style = kit.getStyleSheet(); style.addRule("body { padding: 5px; }"); style.addRule("ul { margin: 5px 15px; }"); style.addRule(".error { font-family: Courier,Courier New,Console,System; color: #ff0000; white-space: pre; }"); // Initialize setEditorKit(kit); setEditable(false); updateDebugInfo(); } /** * Gets the processing context this component is using for displaying * debug information on a node. * * @return the context, or <code>null</code> if no context is being used */ public Processor getProcessingContext() { return processor; } /** * Sets the processing context this component should use for displaying * debug information on a node. * * @param context the context, or <code>null</code> if no context should be used */ public void setProcessingContext(Processor context) { if(this.processor != context) { this.processor = context; updateDebugInfo(); } } /** * Gets the node whose debug information this component is currently displaying. * * @return the node */ public OpNode getNode() { return node; } /** * Sets the node whose debug information this component should display. * * @param node the node to set */ public void setNode(OpNode node) { if(this.node != node) { this.node = node; updateDebugInfo(); } } /** * Updates the debug info for the current node/processing context. */ public void updateDebugInfo() { String text = "<html><body><i>No debug info available</i></body></html>"; if(processor != null) { final OpContext context = processor.getContext().findChildContext(node); if(context != null) { final StringBuilder sb = new StringBuilder(); sb.append("<html><body>"); sb.append("Inputs:<ul>"); for(InputField field : node.getInputFields()) { sb.append("<li><b>"); sb.append(field.getKey()); sb.append("</b>: "); final Object value = context.get(field); sb.append(value == null ? "undefined" : value); sb.append("</li>"); } sb.append("</ul>Outputs:<ul>"); for(OutputField field : node.getOutputFields()) { sb.append("<li><b>"); sb.append(field.getKey()); sb.append("</b>: "); final Object value = context.get(field); sb.append(value == null ? "undefined" : value); sb.append("</li>"); } sb.append("</ul>"); sb.append("</body></html>"); text = sb.toString(); } } setText(text); } }