001 /******************************************************************************
002 * Copyright (C) MActor Developers. All rights reserved. *
003 * ---------------------------------------------------------------------------*
004 * This file is part of MActor. *
005 * *
006 * MActor is free software; you can redistribute it and/or modify *
007 * it under the terms of the GNU General Public License as published by *
008 * the Free Software Foundation; either version 2 of the License, or *
009 * (at your option) any later version. *
010 * *
011 * MActor is distributed in the hope that it will be useful, *
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
014 * GNU General Public License for more details. *
015 * *
016 * You should have received a copy of the GNU General Public License *
017 * along with MActor; if not, write to the Free Software *
018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
019 ******************************************************************************/
020 package org.mactor.ui.gui.testrunner;
021
022 import java.awt.BorderLayout;
023 import java.awt.Color;
024 import java.awt.Component;
025 import java.awt.Font;
026 import java.awt.event.ActionEvent;
027 import java.awt.event.ActionListener;
028 import java.util.HashSet;
029
030 import javax.swing.Icon;
031 import javax.swing.JLabel;
032 import javax.swing.JPanel;
033 import javax.swing.JScrollPane;
034 import javax.swing.JTextArea;
035 import javax.swing.JTree;
036 import javax.swing.Timer;
037 import javax.swing.event.TreeModelListener;
038 import javax.swing.tree.DefaultTreeCellRenderer;
039 import javax.swing.tree.TreeModel;
040 import javax.swing.tree.TreePath;
041
042 import org.mactor.framework.MactorException;
043 import org.mactor.framework.TestEvent;
044 import org.mactor.ui.gui.GuiUtil;
045 import org.mactor.ui.gui.project.ProjectNodeType;
046 import org.mactor.ui.gui.project.ProjectTreeNode;
047
048 public class RunningTestTreePanel extends JPanel {
049 JTree tree = new JTree();
050 JTextArea messageText = new JTextArea(10, 50);
051 Timer timer = new Timer(400, new ActionListener() {
052 public void actionPerformed(ActionEvent e) {
053 if (runningColor.equals(runningColor1))
054 runningColor = runningColor2;
055 else
056 runningColor = runningColor1;
057 tree.validate();
058 tree.repaint();
059 }
060 });
061 public RunningTestTreePanel(ProjectTreeNode node) throws MactorException {
062 super(new BorderLayout());
063 tree.setModel(new ProjectModel(node));
064 tree.setCellRenderer(new ProjectTreeCellRenderer());
065 expandAll(tree, true);
066 JScrollPane sp = new JScrollPane(tree);
067 // sp.setPreferredSize(new Dimension(300, 300));
068 add(sp, BorderLayout.CENTER);
069 messageText.setEditable(false);
070 messageText.setFont(messageText.getFont().deriveFont(Font.ITALIC));
071 add(messageText, BorderLayout.SOUTH);
072 }
073 public void expandAll(JTree tree, boolean expand) {
074 ProjectTreeNode root = (ProjectTreeNode) tree.getModel().getRoot();
075 // Traverse tree from root
076 expandAll(tree, new TreePath(root), expand);
077 }
078 private void expandAll(JTree tree, TreePath parent, boolean expand) {
079 // Traverse children
080 ProjectTreeNode node = (ProjectTreeNode) parent.getLastPathComponent();
081 if (node.getChildCount() >= 0) {
082 for (ProjectTreeNode n : node.getChildNodes()) {
083 TreePath path = parent.pathByAddingChild(n);
084 expandAll(tree, path, expand);
085 }
086 }
087 if (expand) {
088 tree.expandPath(parent);
089 } else {
090 tree.collapsePath(parent);
091 }
092 }
093 public static class RunningTestModel {
094 String last = null;
095 boolean complete = false;
096 boolean success;
097 HashSet<String> executed = new HashSet<String>();
098 String message;
099 boolean running = false;
100 public void reset() {
101 last = null;
102 complete = false;
103 executed.clear();
104 }
105 public void addEvent(TestEvent event) {
106 if (event.isStartEventType()) {
107 String name = event.getNode().getName();
108 executed.add(name);
109 last = name;
110 running = true;
111 } else if (event.isTestCompleteEvent()) {
112 success = event.isSuccessful();
113 complete = true;
114 running = false;
115 }
116 if (event.getCause() != null)
117 message = event.getCause().getMessage();
118 else
119 message = event.getOutputText();
120 }
121 public boolean hasBeenExecuted(String nodeName) {
122 return executed.contains(nodeName);
123 }
124 public boolean isComplete() {
125 return complete;
126 }
127 public String getLast() {
128 return last;
129 }
130 public String getMessage() {
131 return message;
132 }
133 public boolean isRunning() {
134 return running;
135 }
136 public boolean isSuccess() {
137 return success;
138 }
139 }
140 RunningTestModel rtModel = new RunningTestModel();
141 public void setModel(RunningTestModel rtModel) {
142 if (rtModel == null)
143 throw new RuntimeException("RunningTestModel can not be null!");
144 this.rtModel = rtModel;
145 if (rtModel.isRunning() && !timer.isRunning())
146 timer.start();
147 else if (rtModel.isComplete() && timer.isRunning())
148 timer.stop();
149 messageText.setText(rtModel.getMessage());
150 tree.validate();
151 tree.repaint();
152 }
153 public class ProjectModel implements TreeModel {
154 ProjectTreeNode root;// = new
155 public ProjectModel(ProjectTreeNode root) throws MactorException {
156 this.root = root;
157 }
158 public Object getChild(Object node, int index) {
159 return ((ProjectTreeNode) node).getChildNode(index);
160 }
161 public int getChildCount(Object node) {
162 return ((ProjectTreeNode) node).getChildCount();
163 }
164 public int getIndexOfChild(Object node, Object child) {
165 return ((ProjectTreeNode) node).getIndexOfChild((ProjectTreeNode) child);
166 }
167 public ProjectTreeNode getRoot() {
168 return root;
169 }
170 public boolean isLeaf(Object node) {
171 return ((ProjectTreeNode) node).getChildCount() == 0;
172 }
173 public void valueForPathChanged(TreePath path, Object newValue) {
174 }
175 public void addTreeModelListener(TreeModelListener l) {
176 }
177 public void removeTreeModelListener(TreeModelListener l) {
178 }
179 }
180 JLabel ref = new JLabel();
181 Font runningFont = ref.getFont().deriveFont(Font.ITALIC);
182 Font normalFont = ref.getFont();
183 Font doneFont = ref.getFont();
184 Color runningColor1 = Color.WHITE;
185 Color runningColor2 = ref.getForeground();
186 Color runningColor = runningColor1;
187 Color doneColor = Color.GREEN;
188 Color failedColor = Color.RED.darker();
189 Color notDoneColor = ref.getForeground().brighter().brighter().brighter().brighter();
190 class ProjectTreeCellRenderer extends DefaultTreeCellRenderer {
191 private final Icon INCOMING_ICON = GuiUtil.loadIcon("/incoming_16.PNG");
192 private final Icon SUBSCR_ICON = GuiUtil.loadIcon("/subscribe_16.PNG");
193 private final Icon CONDITION_ICON = GuiUtil.loadIcon("/condition_16.PNG");
194 private final Icon LOOP_ICON = GuiUtil.loadIcon("/loop_16.PNG");
195 private final Icon ACTION_ICON = GuiUtil.loadIcon("/action_16.PNG");
196 private final Icon VALUE_EXTRACT_ICON = GuiUtil.loadIcon("/value_extract_16.PNG");
197 private final Icon OUTGOING_ICON = GuiUtil.loadIcon("/outgoing_16.PNG");
198 private final Icon OUTGOING_RESP_ICON = GuiUtil.loadIcon("/outgoing_resp_16.PNG");
199 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean focus) {
200 Component com = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, focus);
201 ProjectTreeNode node = (ProjectTreeNode) value;
202 if (node != null) {
203 if (ProjectNodeType.T_MESSAGE_PUBLISH.equals(node.getNodeType()))
204 setIcon(OUTGOING_ICON);
205 else if (ProjectNodeType.T_MESSAGE_RECEIVE.equals(node.getNodeType()))
206 setIcon(INCOMING_ICON);
207 else if (ProjectNodeType.T_MESSAGE_RESPOND.equals(node.getNodeType()))
208 setIcon(OUTGOING_RESP_ICON);
209 else if (ProjectNodeType.T_MESSAGE_SUBSCRIBE.equals(node.getNodeType()))
210 setIcon(SUBSCR_ICON);
211 else if (ProjectNodeType.T_CONDITION.equals(node.getNodeType()))
212 setIcon(CONDITION_ICON);
213 else if (ProjectNodeType.T_LOOP.equals(node.getNodeType()))
214 setIcon(LOOP_ICON);
215 else if (ProjectNodeType.T_ACTION.equals(node.getNodeType()))
216 setIcon(ACTION_ICON);
217 else if (ProjectNodeType.T_VALUE.equals(node.getNodeType()))
218 setIcon(VALUE_EXTRACT_ICON);
219 if (rtModel.isComplete() && node.getName().equals(rtModel.getLast())) {
220 if (rtModel.isSuccess()) {
221 setFont(doneFont);
222 setForeground(doneColor);
223 } else {
224 setFont(doneFont);
225 setForeground(failedColor);
226 }
227 } else if (node.getName().equals(rtModel.getLast())) {
228 setFont(runningFont);
229 setForeground(runningColor);
230 } else if (rtModel.hasBeenExecuted(node.getName())) {
231 setFont(doneFont);
232 setForeground(doneColor);
233 } else {
234 setFont(normalFont);
235 setForeground(notDoneColor);
236 }
237 }
238 return com;
239 }
240 }
241 }