001 /** 002 * planningtool - A Planning Tool with Critiquing Support. 003 * 004 * Copyright (C) 2006 olale 005 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU General Public License 008 * as published by the Free Software Foundation; either version 2 009 * of the License, or (at your option) any later version. 010 011 * This program 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 this program; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 020 * Contact information: 021 * E-mail: olale@ida.liu.se 022 * olale@lysator.liu.se 023 */ 024 package se.liu.ida.critiquer.gui; 025 026 import java.awt.BorderLayout; 027 import java.awt.Component; 028 import java.awt.Dimension; 029 import java.awt.GridLayout; 030 import java.awt.Shape; 031 import java.util.ArrayList; 032 import java.util.List; 033 import java.util.Vector; 034 035 import javax.swing.JLabel; 036 import javax.swing.JPanel; 037 038 import org.tigris.gef.base.Editor; 039 import org.tigris.gef.event.GraphSelectionEvent; 040 import org.tigris.gef.event.GraphSelectionListener; 041 import org.tigris.gef.graph.presentation.JGraph; 042 043 import se.liu.ida.critiquer.activities.Activity; 044 import se.liu.ida.critiquer.activities.ActivityUtils; 045 import se.liu.ida.critiquer.activities.parameters.ActivityParameter; 046 import se.liu.ida.critiquer.activities.parameters.AgentParameter; 047 import se.liu.ida.critiquer.activities.parameters.CommanderParameter; 048 import se.liu.ida.critiquer.gui.graph.ActivityFigNode; 049 import se.liu.ida.critiquer.gui.graph.ActivityNode; 050 import se.liu.ida.critiquer.mics.ReferenceHolder; 051 052 /** 053 * 054 * <p> 055 * This view is used to allocate resources to Commanders. Here's how it works: 056 * </p> 057 * 058 * <ul> 059 * 060 * <li>The user selects a Commander by selecting any of the activities that 061 * have commanders allocated to them (marked as gray) </li> 062 * 063 * <li>When an activity with a commander is selected, all activities that this 064 * commander is selected to take care of are marked as selected. Therefore, we 065 * mark that there is a <i>Commander</i> selected, not an individual 066 * <i>Activity</i> </li> 067 * 068 * <li>When an Agent is dragged from the list at the bottom to the activity 069 * canvas, the selected Agent is added to the list of agents the <i>Commander</i> 070 * controls, that is, it is made available to all activities that the 071 * <i>Commander</i> is in charge of. </li> 072 * 073 * <li>If there are sub-activities to any of those activities that have 074 * commanders associated with them, they also have the agent available to them. 075 * This may not be the desired behaviour, but for now that is the way it works. 076 * </li> 077 * 078 * </ul> 079 * 080 * @author olale 081 * 082 */ 083 public class ResourceView extends AbstractView implements 084 /** 085 * We don't need to implement ActivityUpdateListener since the graph model is 086 * the same as the one used by the task view 087 */ 088 // ActivityUpdateListener, 089 TransferListener { 090 091 /** 092 * 093 */ 094 private static final long serialVersionUID = 1L; 095 096 private transient JPanel resourcePanel; 097 098 private JGraph graph; 099 100 protected Component defaultLabel; 101 102 private boolean internalSelectionUpdate; 103 104 protected Activity selectedActivity; 105 106 private JPanel southPanel; 107 108 /** 109 * When we use the graph view, we use this constructor instead. 110 */ 111 112 public ResourceView() { 113 super(new BorderLayout()); 114 ReferenceHolder.resourceView = this; 115 graph = new JGraph(ReferenceHolder.getGraphModel()); 116 // graph.getEditor().setGridHidden(true); 117 Dimension graphSize = new Dimension(500, 500); 118 graph.setDrawingSize(graphSize); 119 graph.setPreferredSize(graphSize); 120 defaultLabel = new JLabel("No resources to display"); 121 internalSelectionUpdate = false; 122 /** 123 * Funky way to make sure we select all those activities that have the 124 * same commander, so that they all receive the same agent assignments 125 */ 126 127 final GraphSelectionListener graphSelectionHandler = new GraphSelectionListener() { 128 129 public void selectionChanged(GraphSelectionEvent gse) { 130 Vector selection = gse.getSelections(); 131 if (!internalSelectionUpdate) { 132 if (selection.size() == 1 && selection.get(0) instanceof ActivityFigNode) { 133 ActivityFigNode activityFigNode = (ActivityFigNode) selection.get(0); 134 selectedActivity = activityFigNode.getActivityNode().getActivity(); 135 updateResourcePanel(selectedActivity); 136 ActivityParameter commanderParam = ActivityUtils.getParamByClassAndName(selectedActivity, 137 CommanderParameter.class, 138 "commander"); 139 if (selectedActivity.isAgentAssignable()) { 140 internalSelectionUpdate = true; 141 List nodes = graph.getGraphModel().getNodes(); 142 Editor editor = graph.getEditor(); 143 for (Object object : nodes) { 144 if (object instanceof ActivityNode) { 145 ActivityNode node = (ActivityNode) object; 146 ActivityParameter commanderParam2 = ActivityUtils.getParamByClassAndName(node.getActivity(), 147 CommanderParameter.class, 148 "commander"); 149 if (node.getActivity().isAgentAssignable() && commanderParam.getValue() 150 .equals(commanderParam2.getValue())) { 151 editor.getSelectionManager() 152 .addToSelection(node.presentationFor(editor.getLayerManager() 153 .getActiveLayer())); 154 } 155 } 156 } 157 editor.damageAll(); 158 internalSelectionUpdate = false; 159 } 160 } else { 161 updateResourcePanel(null); 162 } 163 164 } 165 166 } 167 168 }; 169 TaskView.addGraphSelectionListener(graph, graphSelectionHandler); 170 171 graph.setTransferHandler(AgentTransferHandler.getAgentTransferHandler()); 172 AgentTransferHandler.getAgentTransferHandler().addTransferListener(this); 173 Activity.addNameChangeListener(new NameChangeListener() { 174 175 public void nameChanged() { 176 graph.revalidate(); 177 graph.repaint(); 178 } 179 180 }); 181 resourcePanel = new JPanel(new GridLayout(0, 1)); 182 183 add(graph, BorderLayout.CENTER); 184 southPanel = new JPanel(new BorderLayout()); 185 southPanel.add(resourcePanel, BorderLayout.CENTER); 186 southPanel.add(critiqueComponent.getPanel(), BorderLayout.SOUTH); 187 188 add(southPanel, BorderLayout.SOUTH); 189 } 190 191 protected void updateResourcePanel(Activity activity) { 192 resourcePanel.removeAll(); 193 194 if (activity != null) { 195 AgentParameter mainAgentParameter = ActivityUtils.getMainAgentParameter(activity); 196 if (mainAgentParameter != null) { 197 resourcePanel.add(mainAgentParameter.getAgentPanel()); 198 resourcePanel.add(new TrashLabel()); 199 } 200 } else { 201 resourcePanel.add(defaultLabel); 202 } 203 revalidate(); 204 repaint(); 205 } 206 207 public Shape getActivityArea(Activity activity) { 208 Shape activityShape = null; 209 activityShape = TaskView.getActivityArea(graph, activity); 210 return activityShape; 211 } 212 213 public ArrayList<Activity> getEvaluationActivities() { 214 ArrayList<Activity> activities = new ArrayList<Activity>(); 215 Vector figs = graph.getEditor().getSelectionManager().getFigs(); 216 for (Object object : figs) { 217 if (object instanceof ActivityFigNode) { 218 ActivityFigNode activityFig = (ActivityFigNode) object; 219 activities.add(activityFig.getActivityNode().getActivity()); 220 } 221 } 222 return activities; 223 } 224 225 public void transferComplete() { 226 // treePane.setFreezed(false); 227 revalidate(); 228 repaint(); 229 } 230 231 public void transferInitialized() { 232 // treePane.setFreezed(true); 233 } 234 235 public JPanel getResourcePanel() { 236 return resourcePanel; 237 } 238 239 /** 240 * @return Returns the graph. 241 */ 242 public JGraph getGraph() { 243 return graph; 244 } 245 246 }