View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
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 			desktopPanel.getComponent().requestFocusInWindow();
201 		}
202 		else
203 			Toolkit.getDefaultToolkit().beep();
204 
205 		enableWindowActions();
206 		
207 		return currentPanel;
208 	}
209 	
210 	private JInternalFrame createContentFrame(DesktopPanel desktopPanel)
211 	{
212 		desktopPanel.addPropertyChangeListener(desktopPanelPropertyChangeListener);
213 		
214 		JComponent panel = desktopPanel.getComponent();
215 		panel.setOpaque(true);
216 
217 		String title = desktopPanel.getTitle();
218 
219 		JInternalFrame frame = new JInternalFrame(title, true, true, true, true);
220 		frame.addInternalFrameListener(internalFrameListener);
221 		frame.setContentPane(panel);
222 		frame.setSize(panel.getPreferredSize());
223 		frame.setVisible(true);
224 		frame.setFrameIcon( desktopPanel.getIcon() );
225 		frame.setToolTipText( desktopPanel.getDescription() );
226 		frame.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
227 		frame.setLocation(xOffset * (openFrameCount % 10), yOffset * (openFrameCount % 10));
228 		frame.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory
229 				.createEmptyBorder(2, 2, 2, 2)));
230 		openFrameCount++;
231 		return frame;
232 	}
233 
234 	public boolean closeDesktopPanel(ModelItem modelItem)
235 	{
236 		try
237 		{
238 			if (modelItemToInternalFrameMap.containsKey(modelItem))
239 			{
240 				JInternalFrame frame = modelItemToInternalFrameMap.get(modelItem);
241 				frame.doDefaultCloseAction();
242 				return frame.isClosed();
243 			}
244 		
245 			return false;
246 		}
247 		finally
248 		{
249 			enableWindowActions();
250 		}
251 	}
252 
253 	private class InternalDesktopFrameListener extends InternalFrameAdapter
254 	{
255 		public void internalFrameClosing(InternalFrameEvent e)
256 		{
257 			DesktopPanel desktopPanel = internalFrameToDesktopPanelMap.get(e.getInternalFrame());
258 			if ( !transferring && !desktopPanel.onClose( true ))
259 			{
260 				return;
261 			}
262 
263 			desktopPanel.removePropertyChangeListener(desktopPanelPropertyChangeListener);
264 
265 			modelItemToInternalFrameMap.remove( desktopPanel.getModelItem() );
266 			internalFrameToDesktopPanelMap.remove( e.getInternalFrame() );
267 
268 			e.getInternalFrame().dispose();
269 
270 			if( !transferring )
271 				fireDesktopPanelClosed(desktopPanel);
272 		}
273 
274 		public void internalFrameActivated(InternalFrameEvent e)
275 		{
276 			currentPanel = internalFrameToDesktopPanelMap.get(e.getInternalFrame());
277 			if (currentPanel != null)
278 			{
279 				fireDesktopPanelSelected(currentPanel);
280 			}
281 			
282 			enableWindowActions();
283 		}
284 
285 		public void internalFrameDeactivated( InternalFrameEvent e )
286 		{
287 			currentPanel = null;
288 			enableWindowActions();
289 		}
290 	}
291 
292 	public class CloseCurrentAction extends AbstractAction
293 	{
294 		public CloseCurrentAction()
295 		{
296 			super("Close Current");
297 			putValue(Action.SHORT_DESCRIPTION, "Closes the current window");
298 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu F4" ));
299 
300 		}
301 
302 		public void actionPerformed(ActionEvent e)
303 		{
304 			JInternalFrame frame = desktopPane.getSelectedFrame();
305 			if (frame != null)
306 				closeDesktopPanel(internalFrameToDesktopPanelMap.get(frame));
307 		}
308 	}
309 
310 	public class CloseOtherAction extends AbstractAction
311 	{
312 		public CloseOtherAction()
313 		{
314 			super("Close Others");
315 			putValue(Action.SHORT_DESCRIPTION, "Closes all windows except the current one");
316 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu alt O" ));
317 		}
318 
319 		public void actionPerformed(ActionEvent e)
320 		{
321 			JInternalFrame frame = desktopPane.getSelectedFrame();
322 			if (frame == null)
323 				return;
324 
325 			Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap.keySet().iterator();
326 			while (i.hasNext())
327 			{
328 				JInternalFrame f = i.next();
329 				if (f != frame)
330 				{
331 					closeDesktopPanel(internalFrameToDesktopPanelMap.get(f));
332 					i = internalFrameToDesktopPanelMap.keySet().iterator();
333 				}
334 			}
335 		}
336 	}
337 
338 	public class CloseAllAction extends AbstractAction
339 	{
340 		public CloseAllAction()
341 		{
342 			super("Close All");
343 			putValue(Action.SHORT_DESCRIPTION, "Closes all windows");
344 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu alt L" ));
345 		}
346 
347 		public void actionPerformed(ActionEvent e)
348 		{
349 			while (internalFrameToDesktopPanelMap.size() > 0)
350 			{
351 				Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap.keySet().iterator();
352 				try
353 				{
354 					i.next().setClosed(true);
355 				}
356 				catch (PropertyVetoException e1)
357 				{
358 					e1.printStackTrace();
359 				}
360 			}
361 
362 			internalFrameToDesktopPanelMap.clear();
363 			modelItemToInternalFrameMap.clear();
364 
365 			JInternalFrame[] allFrames = desktopPane.getAllFrames();
366 			for (JInternalFrame frame : allFrames)
367 			{
368 				frame.doDefaultCloseAction();
369 			}
370 			
371 			enableWindowActions();
372 		}
373 	}
374 
375 	public ActionList getActions()
376 	{
377 		return actions;
378 	}
379 
380 	private class DesktopPanelPropertyChangeListener implements PropertyChangeListener
381 	{
382 		public void propertyChange(PropertyChangeEvent evt)
383 		{
384 			DesktopPanel desktopPanel = (DesktopPanel) evt.getSource();
385 			JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
386 			if( frame != null )
387 			{
388 				if (evt.getPropertyName().equals(DesktopPanel.TITLE_PROPERTY))
389 				{
390 					frame.setTitle(desktopPanel.getTitle());
391 				}
392 				else if (evt.getPropertyName().equals(DesktopPanel.ICON_PROPERTY))
393 				{
394 					frame.setFrameIcon(desktopPanel.getIcon());
395 				}
396 			}
397 		}
398 	}
399 
400 	public DesktopPanel[] getDesktopPanels()
401 	{
402 		return internalFrameToDesktopPanelMap.values().toArray(new DesktopPanel[internalFrameToDesktopPanelMap.size()]);
403 	}
404 
405 	public DesktopPanel getDesktopPanel(ModelItem modelItem)
406 	{
407 		return internalFrameToDesktopPanelMap.get( modelItem );
408 	}
409 
410 	public DesktopPanel showDesktopPanel( DesktopPanel desktopPanel )
411 	{
412 		JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
413 		if( frame != null )
414 		{
415 			try
416 			{
417 				desktopPane.getDesktopManager().deiconifyFrame(frame);
418 				frame.setSelected(true);
419 				frame.moveToFront();
420 			}
421 			catch (Exception e)
422 			{
423 				e.printStackTrace();
424 			}			
425 		}
426 		else
427 		{
428 			frame = createContentFrame( desktopPanel );
429 			desktopPane.add( frame );
430 			
431 			if( desktopPanel.getModelItem() != null )
432 				modelItemToInternalFrameMap.put(desktopPanel.getModelItem(), frame);
433 			
434 			internalFrameToDesktopPanelMap.put( frame, desktopPanel );
435 			fireDesktopPanelCreated(desktopPanel);
436 			frame.moveToFront();
437 			desktopPanel.getComponent().requestFocusInWindow();
438 		}
439 		
440 		currentPanel = desktopPanel;
441 		enableWindowActions();
442 
443 		return desktopPanel;
444 	}
445 	
446 	class SoapUIDesktopPane extends JDesktopPane
447 	{
448 		Image img;
449 		private int imageWidth;
450 		private int imageHeight;
451 
452 		public SoapUIDesktopPane()
453 		{
454 			try
455 			{
456 				File file = new File("soapui-background.gif");
457 				if( !file.exists())
458 					file = new File("soapui-background.jpg");
459 				if( !file.exists())
460 					file = new File("soapui-background.png");
461 				
462 				if( file.exists())
463 				{
464 					img = javax.imageio.ImageIO.read(file);
465 					imageWidth = img.getWidth(this);
466 					imageHeight = img.getHeight(this);
467 				}
468 			}
469 			catch (Exception e)
470 			{}
471 		}
472 
473 		public void paintComponent(Graphics g)
474 		{
475 			super.paintComponent(g);
476 			
477 			if (img == null)
478 				return;
479 
480 			int x = (this.getWidth() - imageWidth) / 2;
481 			int y = (this.getHeight() - imageHeight) / 2;
482 
483 			g.drawImage(img, x, y, imageWidth, imageHeight, this);
484 		}
485 	}
486 
487 	public void transferTo( SoapUIDesktop newDesktop )
488 	{
489 		transferring = true;
490 		
491 		List<DesktopPanel> values = new ArrayList<DesktopPanel>(internalFrameToDesktopPanelMap.values());
492 		for( DesktopPanel desktopPanel : values )
493 		{
494 			closeDesktopPanel( desktopPanel );
495 			newDesktop.showDesktopPanel( desktopPanel );
496 		}
497 		
498 		transferring = false;
499 	}
500 }