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 			JInternalFrame[] frames = internalFrameToDesktopPanelMap.keySet().toArray( new JInternalFrame[internalFrameToDesktopPanelMap.size()] );
    330 			for (JInternalFrame f : frames)
    331 			{
    332 				if (f != frame)
    333 				{
    334 					closeDesktopPanel(internalFrameToDesktopPanelMap.get(f));
    335 				}
    336 			}
    337 		}
    338 	}
    339
    340 	public class CloseAllAction extends AbstractAction
    341 	{
    342 		public CloseAllAction()
    343 		{
    344 			super("Close All");
    345 			putValue(Action.SHORT_DESCRIPTION, "Closes all windows");
    346 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu alt L" ));
    347 		}
    348
    349 		public void actionPerformed(ActionEvent e)
    350 		{
    351 			closeAll();
    352 		}
    353 	}
    354
    355 	public ActionList getActions()
    356 	{
    357 		return actions;
    358 	}
    359
    360 	private class DesktopPanelPropertyChangeListener implements PropertyChangeListener
    361 	{
    362 		public void propertyChange(PropertyChangeEvent evt)
    363 		{
    364 			DesktopPanel desktopPanel = (DesktopPanel) evt.getSource();
    365 			JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
    366 			if( frame != null )
    367 			{
    368 				if (evt.getPropertyName().equals(DesktopPanel.TITLE_PROPERTY))
    369 				{
    370 					frame.setTitle(desktopPanel.getTitle());
    371 				}
    372 				else if (evt.getPropertyName().equals(DesktopPanel.ICON_PROPERTY))
    373 				{
    374 					frame.setFrameIcon(desktopPanel.getIcon());
    375 				}
    376 			}
    377 		}
    378 	}
    379
    380 	public DesktopPanel[] getDesktopPanels()
    381 	{
    382 		return internalFrameToDesktopPanelMap.values().toArray(new DesktopPanel[internalFrameToDesktopPanelMap.size()]);
    383 	}
    384
    385 	public DesktopPanel getDesktopPanel(ModelItem modelItem)
    386 	{
    387 		return internalFrameToDesktopPanelMap.get( modelItem );
    388 	}
    389
    390 	public DesktopPanel showDesktopPanel( DesktopPanel desktopPanel )
    391 	{
    392 		JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
    393 		if( frame != null )
    394 		{
    395 			try
    396 			{
    397 				desktopPane.getDesktopManager().deiconifyFrame(frame);
    398 				frame.setSelected(true);
    399 				frame.moveToFront();
    400 			}
    401 			catch (Exception e)
    402 			{
    403 				SoapUI.logError( e );
    404 			}
    405 		}
    406 		else
    407 		{
    408 			frame = createContentFrame( desktopPanel );
    409 			desktopPane.add( frame );
    410
    411 			if( desktopPanel.getModelItem() != null )
    412 				modelItemToInternalFrameMap.put(desktopPanel.getModelItem(), frame);
    413
    414 			internalFrameToDesktopPanelMap.put( frame, desktopPanel );
    415 			fireDesktopPanelCreated(desktopPanel);
    416 			frame.moveToFront();
    417 			desktopPanel.getComponent().requestFocusInWindow();
    418 		}
    419
    420 		currentPanel = desktopPanel;
    421 		enableWindowActions();
    422
    423 		return desktopPanel;
    424 	}
    425
    426 	class SoapUIDesktopPane extends JDesktopPane
    427 	{
    428 		Image img;
    429 		private int imageWidth;
    430 		private int imageHeight;
    431
    432 		public SoapUIDesktopPane()
    433 		{
    434 			try
    435 			{
    436 				File file = new File("soapui-background.gif");
    437 				if( !file.exists())
    438 					file = new File("soapui-background.jpg");
    439 				if( !file.exists())
    440 					file = new File("soapui-background.png");
    441
    442 				if( file.exists())
    443 				{
    444 					img = javax.imageio.ImageIO.read(file);
    445 					imageWidth = img.getWidth(this);
    446 					imageHeight = img.getHeight(this);
    447 				}
    448 			}
    449 			catch (Exception e)
    450 			{}
    451 		}
    452
    453 		public void paintComponent(Graphics g)
    454 		{
    455 			super.paintComponent(g);
    456
    457 			if (img == null)
    458 				return;
    459
    460 			int x = (this.getWidth() - imageWidth) / 2;
    461 			int y = (this.getHeight() - imageHeight) / 2;
    462
    463 			g.drawImage(img, x, y, imageWidth, imageHeight, this);
    464 		}
    465 	}
    466
    467 	public void transferTo( SoapUIDesktop newDesktop )
    468 	{
    469 		transferring = true;
    470
    471 		List<DesktopPanel> values = new ArrayList<DesktopPanel>(internalFrameToDesktopPanelMap.values());
    472 		for( DesktopPanel desktopPanel : values )
    473 		{
    474 			closeDesktopPanel( desktopPanel );
    475 			newDesktop.showDesktopPanel( desktopPanel );
    476 		}
    477
    478 		transferring = false;
    479 	}
    480
    481 	public boolean closeAll()
    482 	{
    483 		while (internalFrameToDesktopPanelMap.size() > 0)
    484 		{
    485 			Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap.keySet().iterator();
    486 			try
    487 			{
    488 				i.next().setClosed(true);
    489 			}
    490 			catch (PropertyVetoException e1)
    491 			{
    492 				SoapUI.logError( e1 );
    493 			}
    494 		}
    495
    496 		internalFrameToDesktopPanelMap.clear();
    497 		modelItemToInternalFrameMap.clear();
    498
    499 		JInternalFrame[] allFrames = desktopPane.getAllFrames();
    500 		for (JInternalFrame frame : allFrames)
    501 		{
    502 			frame.doDefaultCloseAction();
    503 		}
    504
    505 		enableWindowActions();
    506 		return true;
    507 	}
    508 }