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 }