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