View Javadoc

1   /*
2    *  soapUI, copyright (C) 2006 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.ui.desktop.standalone;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Graphics;
17  import java.awt.Image;
18  import java.awt.Toolkit;
19  import java.awt.event.ActionEvent;
20  import java.beans.PropertyChangeEvent;
21  import java.beans.PropertyChangeListener;
22  import java.beans.PropertyVetoException;
23  import java.io.File;
24  import java.util.ArrayList;
25  import java.util.HashMap;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Map;
29  
30  import javax.swing.AbstractAction;
31  import javax.swing.Action;
32  import javax.swing.BorderFactory;
33  import javax.swing.JComponent;
34  import javax.swing.JDesktopPane;
35  import javax.swing.JInternalFrame;
36  import javax.swing.JPanel;
37  import javax.swing.JScrollPane;
38  import javax.swing.event.InternalFrameAdapter;
39  import javax.swing.event.InternalFrameEvent;
40  
41  import com.eviware.soapui.model.ModelItem;
42  import com.eviware.soapui.model.PanelBuilder;
43  import com.eviware.soapui.model.util.PanelBuilderRegistry;
44  import com.eviware.soapui.model.workspace.Workspace;
45  import com.eviware.soapui.support.UISupport;
46  import com.eviware.soapui.support.action.ActionList;
47  import com.eviware.soapui.support.action.DefaultActionList;
48  import com.eviware.soapui.ui.desktop.AbstractSoapUIDesktop;
49  import com.eviware.soapui.ui.desktop.DesktopPanel;
50  import com.eviware.soapui.ui.desktop.SoapUIDesktop;
51  
52  /***
53   * The main soapUI desktop
54   * 
55   * @author Ole.Matzura
56   */
57  
58  public class StandaloneDesktop extends AbstractSoapUIDesktop
59  {
60  	private JDesktopPane desktopPane;
61  	private Map<ModelItem, JInternalFrame> modelItemToInternalFrameMap = new HashMap<ModelItem, JInternalFrame>();
62  	private Map<JInternalFrame, DesktopPanel> internalFrameToDesktopPanelMap = new HashMap<JInternalFrame, DesktopPanel>();
63  	private DesktopPanelPropertyChangeListener desktopPanelPropertyChangeListener = new DesktopPanelPropertyChangeListener();
64  	private InternalDesktopFrameListener internalFrameListener = new InternalDesktopFrameListener();
65  	private ActionList actions;
66  
67  	private DesktopPanel currentPanel;
68  	
69  	private CloseCurrentAction closeCurrentAction = new CloseCurrentAction();
70  	private CloseOtherAction closeOtherAction = new CloseOtherAction();
71  	private CloseAllAction closeAllAction = new CloseAllAction();
72  	
73  	private static int openFrameCount = 0;
74  	private static final int xOffset = 30, yOffset = 30;
75  	private JPanel desktopPanel = new JPanel( new BorderLayout() );
76  	
77  	private boolean transferring;
78  
79  	public StandaloneDesktop(Workspace workspace)
80  	{
81  		super( workspace );
82  
83  		buildUI();
84  
85  		actions = new DefaultActionList( "Desktop" );
86  		actions.addAction(closeCurrentAction);
87  		actions.addAction(closeOtherAction);
88  		actions.addAction(closeAllAction);
89  		
90  		enableWindowActions();
91  	}
92  	
93  	private void enableWindowActions()
94  	{
95  		closeCurrentAction.setEnabled( currentPanel != null && internalFrameToDesktopPanelMap.size() > 0  );
96  		closeOtherAction.setEnabled( currentPanel != null && internalFrameToDesktopPanelMap.size() > 1 );
97  		closeAllAction.setEnabled( internalFrameToDesktopPanelMap.size() > 0 );
98  	}
99  
100 	private void buildUI()
101 	{
102 		desktopPane = new SoapUIDesktopPane();
103 		JScrollPane scrollPane = new JScrollPane(desktopPane);
104 		desktopPanel.add(scrollPane, BorderLayout.CENTER);
105 	}
106 
107 	public JComponent getDesktopComponent()
108 	{
109 		return desktopPanel;
110 	}
111 
112 	public boolean closeDesktopPanel(DesktopPanel desktopPanel)
113 	{
114 		try
115 		{
116 			if( desktopPanel.getModelItem() != null )
117 			{
118 				return closeDesktopPanel(desktopPanel.getModelItem());
119 			}
120 			else
121 			{
122 				JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
123 				if( frame != null )
124 				{
125 					frame.doDefaultCloseAction();
126 					return frame.isClosed();
127 				}
128 //				else
129 //					throw new RuntimeException( "Cannot close unkown DesktopPanel: " + desktopPanel.getTitle() );
130 				
131 				return false;
132 			}
133 		}
134 		finally
135 		{
136 			enableWindowActions();
137 		}
138 	}
139 	
140 	private JInternalFrame getFrameForDesktopPanel( DesktopPanel desktopPanel )
141 	{
142 		for( JInternalFrame frame : internalFrameToDesktopPanelMap.keySet() )
143 		{
144 			if( internalFrameToDesktopPanelMap.get( frame ) == desktopPanel )
145 			{
146 				return frame;
147 			}
148 		}
149 		
150 		return null;
151 	}
152 
153 	public boolean hasDesktopPanel(ModelItem modelItem)
154 	{
155 		return modelItemToInternalFrameMap.containsKey(modelItem);
156 	}
157 
158 	public DesktopPanel showDesktopPanel(ModelItem modelItem)
159 	{
160 		PanelBuilder<ModelItem> panelBuilder = PanelBuilderRegistry.getPanelBuilder( modelItem );
161 		if (modelItemToInternalFrameMap.containsKey(modelItem))
162 		{
163 			JInternalFrame frame = modelItemToInternalFrameMap.get(modelItem);
164 			try
165 			{
166 				desktopPane.getDesktopManager().deiconifyFrame(frame);
167 				frame.setSelected(true);
168 				frame.moveToFront();
169 				currentPanel = internalFrameToDesktopPanelMap.get( frame );
170 			}
171 			catch (PropertyVetoException e)
172 			{
173 				e.printStackTrace();
174 			}
175 		}
176 		else if (panelBuilder != null && panelBuilder.hasDesktopPanel())
177 		{
178 			DesktopPanel desktopPanel = panelBuilder.buildDesktopPanel( modelItem );
179 			if( desktopPanel == null )
180 				return null;
181 			
182 			JInternalFrame frame = createContentFrame(desktopPanel);
183 
184 			desktopPane.add(frame);
185 			try
186 			{
187 				frame.setSelected(true);
188 			}
189 			catch (PropertyVetoException e)
190 			{
191 				e.printStackTrace();
192 			}
193 
194 			modelItemToInternalFrameMap.put(modelItem, frame);
195 			internalFrameToDesktopPanelMap.put(frame, desktopPanel);
196 
197 			fireDesktopPanelCreated(desktopPanel);
198 			
199 			currentPanel = desktopPanel;
200 		}
201 		else
202 			Toolkit.getDefaultToolkit().beep();
203 
204 		enableWindowActions();
205 		
206 		return currentPanel;
207 	}
208 	
209 	private JInternalFrame createContentFrame(DesktopPanel desktopPanel)
210 	{
211 		desktopPanel.addPropertyChangeListener(desktopPanelPropertyChangeListener);
212 		
213 		JComponent panel = desktopPanel.getComponent();
214 		panel.setOpaque(true);
215 
216 		String title = desktopPanel.getTitle();
217 
218 		JInternalFrame frame = new JInternalFrame(title, true, true, true, true);
219 		frame.addInternalFrameListener(internalFrameListener);
220 		frame.setContentPane(panel);
221 		frame.setSize(panel.getPreferredSize());
222 		frame.setVisible(true);
223 		frame.setFrameIcon( desktopPanel.getIcon() );
224 		frame.setToolTipText( desktopPanel.getDescription() );
225 		frame.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
226 		frame.setLocation(xOffset * (openFrameCount % 10), yOffset * (openFrameCount % 10));
227 		frame.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory
228 				.createEmptyBorder(2, 2, 2, 2)));
229 		openFrameCount++;
230 		return frame;
231 	}
232 
233 	public boolean closeDesktopPanel(ModelItem modelItem)
234 	{
235 		try
236 		{
237 			if (modelItemToInternalFrameMap.containsKey(modelItem))
238 			{
239 				JInternalFrame frame = modelItemToInternalFrameMap.get(modelItem);
240 				frame.doDefaultCloseAction();
241 				return frame.isClosed();
242 			}
243 		
244 			return false;
245 		}
246 		finally
247 		{
248 			enableWindowActions();
249 		}
250 	}
251 
252 	private class InternalDesktopFrameListener extends InternalFrameAdapter
253 	{
254 		public void internalFrameClosing(InternalFrameEvent e)
255 		{
256 			DesktopPanel desktopPanel = internalFrameToDesktopPanelMap.get(e.getInternalFrame());
257 			if ( !transferring && !desktopPanel.onClose( true ))
258 			{
259 				return;
260 			}
261 
262 			desktopPanel.removePropertyChangeListener(desktopPanelPropertyChangeListener);
263 
264 			modelItemToInternalFrameMap.remove( desktopPanel.getModelItem() );
265 			internalFrameToDesktopPanelMap.remove( e.getInternalFrame() );
266 
267 			e.getInternalFrame().dispose();
268 
269 			if( !transferring )
270 				fireDesktopPanelClosed(desktopPanel);
271 		}
272 
273 		public void internalFrameActivated(InternalFrameEvent e)
274 		{
275 			currentPanel = internalFrameToDesktopPanelMap.get(e.getInternalFrame());
276 			if (currentPanel != null)
277 			{
278 				fireDesktopPanelSelected(currentPanel);
279 			}
280 			
281 			enableWindowActions();
282 		}
283 
284 		public void internalFrameDeactivated( InternalFrameEvent e )
285 		{
286 			currentPanel = null;
287 			enableWindowActions();
288 		}
289 	}
290 
291 	public class CloseCurrentAction extends AbstractAction
292 	{
293 		public CloseCurrentAction()
294 		{
295 			super("Close Current");
296 			putValue(Action.SHORT_DESCRIPTION, "Closes the current window");
297 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu F4" ));
298 
299 		}
300 
301 		public void actionPerformed(ActionEvent e)
302 		{
303 			JInternalFrame frame = desktopPane.getSelectedFrame();
304 			if (frame != null)
305 				closeDesktopPanel(internalFrameToDesktopPanelMap.get(frame));
306 		}
307 	}
308 
309 	public class CloseOtherAction extends AbstractAction
310 	{
311 		public CloseOtherAction()
312 		{
313 			super("Close Others");
314 			putValue(Action.SHORT_DESCRIPTION, "Closes all windows except the current one");
315 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu alt O" ));
316 		}
317 
318 		public void actionPerformed(ActionEvent e)
319 		{
320 			JInternalFrame frame = desktopPane.getSelectedFrame();
321 			if (frame == null)
322 				return;
323 
324 			Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap.keySet().iterator();
325 			while (i.hasNext())
326 			{
327 				JInternalFrame f = i.next();
328 				if (f != frame)
329 				{
330 					closeDesktopPanel(internalFrameToDesktopPanelMap.get(f));
331 					i = internalFrameToDesktopPanelMap.keySet().iterator();
332 				}
333 			}
334 		}
335 	}
336 
337 	public class CloseAllAction extends AbstractAction
338 	{
339 		public CloseAllAction()
340 		{
341 			super("Close All");
342 			putValue(Action.SHORT_DESCRIPTION, "Closes all windows");
343 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu alt L" ));
344 		}
345 
346 		public void actionPerformed(ActionEvent e)
347 		{
348 			while (internalFrameToDesktopPanelMap.size() > 0)
349 			{
350 				Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap.keySet().iterator();
351 				try
352 				{
353 					i.next().setClosed(true);
354 				}
355 				catch (PropertyVetoException e1)
356 				{
357 					e1.printStackTrace();
358 				}
359 			}
360 
361 			internalFrameToDesktopPanelMap.clear();
362 			modelItemToInternalFrameMap.clear();
363 
364 			JInternalFrame[] allFrames = desktopPane.getAllFrames();
365 			for (JInternalFrame frame : allFrames)
366 			{
367 				frame.doDefaultCloseAction();
368 			}
369 			
370 			enableWindowActions();
371 		}
372 	}
373 
374 	public ActionList getActions()
375 	{
376 		return actions;
377 	}
378 
379 	private class DesktopPanelPropertyChangeListener implements PropertyChangeListener
380 	{
381 		public void propertyChange(PropertyChangeEvent evt)
382 		{
383 			DesktopPanel desktopPanel = (DesktopPanel) evt.getSource();
384 			if (evt.getPropertyName().equals(DesktopPanel.TITLE_PROPERTY))
385 			{
386 				getFrameForDesktopPanel( desktopPanel ).setTitle(desktopPanel.getTitle());
387 			}
388 			else if (evt.getPropertyName().equals(DesktopPanel.ICON_PROPERTY))
389 			{
390 				getFrameForDesktopPanel( desktopPanel ).setFrameIcon(desktopPanel.getIcon());
391 			}
392 		}
393 	}
394 
395 	public DesktopPanel[] getDesktopPanels()
396 	{
397 		return internalFrameToDesktopPanelMap.values().toArray(new DesktopPanel[internalFrameToDesktopPanelMap.size()]);
398 	}
399 
400 	public DesktopPanel getDesktopPanel(ModelItem modelItem)
401 	{
402 		return internalFrameToDesktopPanelMap.get( modelItem );
403 	}
404 
405 	public DesktopPanel showDesktopPanel( DesktopPanel desktopPanel )
406 	{
407 		JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
408 		if( frame != null )
409 		{
410 			try
411 			{
412 				desktopPane.getDesktopManager().deiconifyFrame(frame);
413 				frame.setSelected(true);
414 				frame.moveToFront();
415 			}
416 			catch (Exception e)
417 			{
418 				e.printStackTrace();
419 			}			
420 		}
421 		else
422 		{
423 			frame = createContentFrame( desktopPanel );
424 			desktopPane.add( frame );
425 			internalFrameToDesktopPanelMap.put( frame, desktopPanel );
426 			fireDesktopPanelCreated(desktopPanel);
427 			frame.moveToFront();
428 		}
429 		
430 		currentPanel = desktopPanel;
431 		enableWindowActions();
432 
433 		return desktopPanel;
434 	}
435 	
436 	class SoapUIDesktopPane extends JDesktopPane
437 	{
438 		Image img;
439 		private int imageWidth;
440 		private int imageHeight;
441 
442 		public SoapUIDesktopPane()
443 		{
444 			try
445 			{
446 				File file = new File("soapui-background.gif");
447 				if( !file.exists())
448 					file = new File("soapui-background.jpg");
449 				if( !file.exists())
450 					file = new File("soapui-background.png");
451 				
452 				if( file.exists())
453 				{
454 					img = javax.imageio.ImageIO.read(file);
455 					imageWidth = img.getWidth(this);
456 					imageHeight = img.getHeight(this);
457 				}
458 			}
459 			catch (Exception e)
460 			{}
461 		}
462 
463 		public void paintComponent(Graphics g)
464 		{
465 			super.paintComponent(g);
466 			
467 			if (img == null)
468 				return;
469 
470 			int x = (this.getWidth() - imageWidth) / 2;
471 			int y = (this.getHeight() - imageHeight) / 2;
472 
473 			g.drawImage(img, x, y, imageWidth, imageHeight, this);
474 		}
475 	}
476 
477 	public void transferTo( SoapUIDesktop newDesktop )
478 	{
479 		transferring = true;
480 		
481 		List<DesktopPanel> values = new ArrayList<DesktopPanel>(internalFrameToDesktopPanelMap.values());
482 		for( DesktopPanel desktopPanel : values )
483 		{
484 			closeDesktopPanel( desktopPanel );
485 			newDesktop.showDesktopPanel( desktopPanel );
486 		}
487 		
488 		transferring = false;
489 	}
490 }