View Javadoc

1   /*
2    * @(#) DialogPanelFactory.java Oct 27, 2004
3    * 
4    * 
5    * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
6    * Delft, the Netherlands. All rights reserved.
7    * 
8    * See for project information <a href="http://www.simulation.tudelft.nl/">
9    * www.simulation.tudelft.nl </a>.
10   * 
11   * The source code and binary code of this software is proprietary information
12   * of Delft University of Technology.
13   */
14  package org.gscg.gameleader.dialogs.components;
15  
16  import java.awt.Color;
17  import java.awt.Dimension;
18  import java.lang.reflect.Constructor;
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.Map;
23  
24  import javax.swing.JTabbedPane;
25  import javax.swing.SwingConstants;
26  import javax.swing.UIManager;
27  
28  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
29  import nl.tudelft.simulation.logger.Logger;
30  
31  /***
32   * The DialogPanelFactory is used to create customized JPanels based on the
33   * object given to the factory. If the factory is not able to process the
34   * selected object, null is returned.
35   * <p>
36   * 
37   * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
38   * Delft, the Netherlands. All rights reserved.
39   * 
40   * See for project information <a href="http://www.simulation.tudelft.nl/">
41   * www.simulation.tudelft.nl </a>.
42   * 
43   * The source code and binary code of this software is proprietary information
44   * of Delft University of Technology.
45   * 
46   * @author <a
47   *         href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
48   *         van Houten </a>
49   * @version $Revision: 1.1 $ $Date: 2005/06/16 12:34:09 $
50   * @since 1.0.3
51   */
52  public final class DialogPanelFactory
53  {
54  	/*** the simulator to use */
55  	private static SimulatorInterface simulator = null;
56  
57  	/***
58  	 * Method setSimulator sets the simulator to use.
59  	 * 
60  	 * @param simulator the simulator to use
61  	 */
62  	public static void setSimulator(final SimulatorInterface simulator)
63  	{
64  		DialogPanelFactory.simulator = simulator;
65  	}
66  
67  	/***
68  	 * constructs a new DialogPanelFactory
69  	 */
70  	private DialogPanelFactory()
71  	{
72  		// utility classes should not be instantiated
73  	}
74  
75  	/***
76  	 * the map contains the known actor objects and is initialized during
77  	 * classloading
78  	 */
79  	private static ArrayList knownActorObjects;
80  
81  	/***
82  	 * Method getPanel returns an panel based on the given object
83  	 * 
84  	 * @param object the selected object
85  	 * @return returns an initialized JPanel if the class of the actor is known,
86  	 *         null otherwise
87  	 */
88  	public static JTabbedPane getPanel(final Object object)
89  	{
90  		Class objectClass = object.getClass();
91  		DialogInterface objectPanel = null;
92  
93  		// the structure below enables us to use basic panels e.g. for a
94  		// supplychain actor
95  		// if we would like to use a more customized one (e.g. for a trader),
96  		// this one will be used first
97  		for (int i = 0; i < DialogPanelFactory.knownActorObjects.size(); i++)
98  		{
99  			Map map = (Map) DialogPanelFactory.knownActorObjects.get(i);
100 
101 			for (Iterator it = map.keySet().iterator(); it.hasNext();)
102 			{
103 				Class clazz = (Class) it.next();
104 				if (clazz.isAssignableFrom(objectClass))
105 				{
106 					objectPanel = (DialogInterface) map.get(clazz);
107 					return DialogPanelFactory.createPanel(objectPanel, object);
108 				}
109 			}
110 		}
111 		// we failed to find an actor dialog window
112 		Logger.severe(DialogPanelFactory.class, "find factory",
113 				"Could not find factory for object with class: "
114 						+ object.getClass());
115 		return null;
116 	}
117 
118 	/***
119 	 * Method addFactory allows the adding of panel factories. Based on the
120 	 * class, a lookup is performed to determine the correct position of the
121 	 * factory in the list of factories. If there was no factory present for the
122 	 * given class, the factory is added and true is returned. If there is
123 	 * already a factory present, false is returned.
124 	 * 
125 	 * @param clazz the class to add the factory for
126 	 * @param dialogInterface the dialogInterface
127 	 * @return returns false if the factory could not be added, e.g. when there
128 	 *         is already a factory present for the given class
129 	 */
130 	public static boolean addFactory(final Class clazz,
131 			final DialogInterface dialogInterface)
132 	{
133 		boolean added = false;
134 
135 		if (DialogPanelFactory.knownActorObjects == null)
136 		{
137 			DialogPanelFactory.knownActorObjects = new ArrayList();
138 		}
139 
140 		// we first check whether there is already a factory present
141 		for (int i = DialogPanelFactory.knownActorObjects.size() - 1; i >= 0; i--)
142 		{
143 			Map map = (Map) DialogPanelFactory.knownActorObjects.get(i);
144 			for (Iterator it = map.keySet().iterator(); it.hasNext();)
145 			{
146 				Class key = (Class) it.next();
147 				if (clazz.equals(key))
148 				{
149 					// key is already present, return false
150 					return false;
151 				}
152 			}
153 		}
154 
155 		// we passed the check, add the factory
156 		for (int i = DialogPanelFactory.knownActorObjects.size() - 1; i >= 0; i--)
157 		{
158 			Map map = (Map) DialogPanelFactory.knownActorObjects.get(i);
159 			for (Iterator it = map.keySet().iterator(); it.hasNext();)
160 			{
161 				Class key = (Class) it.next();
162 				if (clazz.isAssignableFrom(key))
163 				{
164 					Map newMap = new HashMap();
165 					newMap.put(clazz, dialogInterface);
166 					DialogPanelFactory.knownActorObjects.add(i, newMap);
167 					added = true;
168 					break;
169 				}
170 			}
171 			if (added)
172 			{
173 				return true;
174 			}
175 		}
176 
177 		// it's a base class, add the factory
178 		if (!added)
179 		{
180 			Map newMap = new HashMap();
181 			newMap.put(clazz, dialogInterface);
182 			DialogPanelFactory.knownActorObjects.add(0, newMap);
183 			return true;
184 		}
185 		return false;
186 	}
187 
188 	/***
189 	 * Method createPanel creates a panel
190 	 * 
191 	 * @param dialogInterface the interface panel
192 	 * @param object the object
193 	 * @return returns an initialized panel
194 	 */
195 	private static JTabbedPane createPanel(
196 			final DialogInterface dialogInterface, final Object object)
197 	{
198 
199 		// set the background of the tabbed pane tabs (why do we need this code
200 		// --> stupid SWING)
201 		UIManager.put("TabbedPane.selected", Color.WHITE);
202 
203 		// initialize panel
204 		JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP,
205 				JTabbedPane.SCROLL_TAB_LAYOUT);
206 		tabbedPane.setFocusable(true);
207 		tabbedPane.setBackground(Color.WHITE);
208 		tabbedPane.setPreferredSize(new Dimension(400, 200));
209 
210 		// add the panels
211 		for (int i = 0; i < dialogInterface.getPanelClassNames().length; i++)
212 		{
213 			AbstractPanel abstractPanel = null;
214 			String abstractPanelClassName = dialogInterface
215 					.getPanelClassNames()[i];
216 			try
217 			{
218 				Class abstractPanelClass = Class
219 						.forName(abstractPanelClassName);
220 				Constructor constructor = null;
221 				try
222 				{
223 					constructor = abstractPanelClass
224 							.getConstructor(new Class[]{Object.class});
225 					abstractPanel = (AbstractPanel) constructor
226 							.newInstance(new Object[]{object});
227 				} catch (Exception exception)
228 				{
229 					// we could not find a suitable constructor
230 					// let's try with the simulator as an extra argument
231 					constructor = abstractPanelClass
232 							.getConstructor(new Class[]{Object.class,
233 									SimulatorInterface.class});
234 					abstractPanel = (AbstractPanel) constructor
235 							.newInstance(new Object[]{object,
236 									DialogPanelFactory.simulator});
237 				}
238 				tabbedPane.add(abstractPanel.getName(), abstractPanel);
239 
240 			} catch (Exception exception)
241 			{
242 				Logger.warning(DialogPanelFactory.class, "createPanel",
243 						"could not load " + abstractPanelClassName);
244 				Logger.warning(DialogPanelFactory.class, "createPanel",
245 						exception);
246 			}
247 		}
248 		return tabbedPane;
249 	}
250 }