View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.support;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Color;
17  import java.awt.Component;
18  import java.awt.Container;
19  import java.awt.Cursor;
20  import java.awt.Dimension;
21  import java.awt.Event;
22  import java.awt.Font;
23  import java.awt.Frame;
24  import java.awt.GraphicsEnvironment;
25  import java.awt.Point;
26  import java.awt.Rectangle;
27  import java.awt.Toolkit;
28  import java.awt.Window;
29  import java.awt.event.ActionEvent;
30  import java.awt.event.ItemEvent;
31  import java.awt.event.ItemListener;
32  import java.awt.event.KeyEvent;
33  import java.io.File;
34  import java.net.URL;
35  import java.util.ArrayList;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  
40  import javax.swing.AbstractAction;
41  import javax.swing.Action;
42  import javax.swing.BorderFactory;
43  import javax.swing.ImageIcon;
44  import javax.swing.JButton;
45  import javax.swing.JComboBox;
46  import javax.swing.JComponent;
47  import javax.swing.JDialog;
48  import javax.swing.JFrame;
49  import javax.swing.JPanel;
50  import javax.swing.JPopupMenu;
51  import javax.swing.JProgressBar;
52  import javax.swing.JRootPane;
53  import javax.swing.JScrollPane;
54  import javax.swing.JSplitPane;
55  import javax.swing.JTabbedPane;
56  import javax.swing.JTable;
57  import javax.swing.KeyStroke;
58  import javax.swing.ScrollPaneConstants;
59  import javax.swing.UIManager;
60  import javax.swing.border.Border;
61  import javax.swing.table.TableCellEditor;
62  import javax.swing.table.TableColumn;
63  
64  import org.syntax.jedit.InputHandler;
65  
66  import com.eviware.soapui.SoapUI;
67  import com.eviware.soapui.SwingPluginSoapUICore;
68  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ToolHost;
69  import com.eviware.soapui.model.ModelItem;
70  import com.eviware.soapui.model.settings.Settings;
71  import com.eviware.soapui.model.testsuite.TestProperty;
72  import com.eviware.soapui.settings.UISettings;
73  import com.eviware.soapui.support.action.swing.ActionList;
74  import com.eviware.soapui.support.components.ConfigurationDialog;
75  import com.eviware.soapui.support.components.JButtonBar;
76  import com.eviware.soapui.support.components.JXToolBar;
77  import com.eviware.soapui.support.components.PreviewCorner;
78  import com.eviware.soapui.support.components.SwingConfigurationDialogImpl;
79  import com.eviware.soapui.support.swing.GradientPanel;
80  import com.eviware.soapui.support.swing.SoapUISplitPaneUI;
81  import com.eviware.soapui.support.swing.SwingUtils;
82  import com.eviware.soapui.ui.desktop.DesktopPanel;
83  import com.eviware.soapui.ui.desktop.SoapUIDesktop;
84  import com.eviware.x.dialogs.XDialogs;
85  import com.eviware.x.dialogs.XFileDialogs;
86  import com.eviware.x.impl.swing.SwingDialogs;
87  import com.eviware.x.impl.swing.SwingFileDialogs;
88  import com.jgoodies.looks.HeaderStyle;
89  import com.jgoodies.looks.Options;
90  
91  /***
92   * Facade for common UI-related tasks
93   * 
94   * @author Ole.Matzura
95   */
96  
97  public class UISupport
98  {
99  	public static final String IMAGES_RESOURCE_PATH = "/com/eviware/soapui/resources/images";
100 	public static final String TOOL_ICON_PATH = "/applications-system.png";
101 	public static final String OPTIONS_ICON_PATH = "/preferences-system.png";
102 	public static final String LOADUI_ICON_PATH = "/runWithLoadui.png";
103 	public static final String CONVERT_TO_LOADUI_ICON_PATH = "/convertLoadTestToLoadUI.png";
104 
105 	// This is needed in Eclipse that has strict class loader constraints.
106 	private static List<ClassLoader> secondaryResourceLoaders = new ArrayList<ClassLoader>();
107 
108 	private static Component frame;
109 	private static Map<String, ImageIcon> iconCache = new HashMap<String, ImageIcon>();
110 	public static Dimension TOOLBAR_BUTTON_DIMENSION;
111 	private static Boolean isWindows;
112 	private static Boolean isMac;
113 
114 	private static XDialogs dialogs;
115 	private static XFileDialogs fileDialogs;
116 	private static UIUtils uiUtils;
117 	private static ToolHost toolHost;
118 	private static Cursor hourglassCursor;
119 	private static Cursor defaultCursor;
120 	private static Boolean isHeadless;
121 
122 	public static final String DEFAULT_EDITOR_FONT = "Courier plain";
123 	public static final int DEFAULT_EDITOR_FONT_SIZE = 11;
124 
125 	static
126 	{
127 		setDialogs( new ConsoleDialogs() );
128 		uiUtils = new SwingUtils();
129 
130 		if( !isHeadless() )
131 			TOOLBAR_BUTTON_DIMENSION = new Dimension( 22, 21 );
132 	}
133 
134 	public static ImageIcon TOOL_ICON = UISupport.createImageIcon( TOOL_ICON_PATH );
135 	public static ImageIcon OPTIONS_ICON = UISupport.createImageIcon( OPTIONS_ICON_PATH );
136 	public static ImageIcon LOADUI_ICON = UISupport.createImageIcon( LOADUI_ICON_PATH );
137 	public static ImageIcon HELP_ICON = UISupport.createImageIcon( "/help-browser.png" );
138 	private static EditorFactory editorFactory = new DefaultEditorFactory();
139 
140 	/***
141 	 * Add a classloader to find resources.
142 	 * 
143 	 * @param loader
144 	 */
145 	public static void addClassLoader( ClassLoader loader )
146 	{
147 		secondaryResourceLoaders.add( loader );
148 	}
149 
150 	/***
151 	 * Set the main frame of this application. This is only used when running
152 	 * under Swing.
153 	 * 
154 	 * @param frame
155 	 */
156 	public static void setMainFrame( Component frame )
157 	{
158 		UISupport.frame = frame;
159 		setDialogs( new SwingDialogs( frame ) );
160 		setFileDialogs( new SwingFileDialogs( frame ) );
161 	}
162 
163 	public static void setDialogs( XDialogs xDialogs )
164 	{
165 		dialogs = xDialogs;
166 	}
167 
168 	public static EditorFactory getEditorFactory()
169 	{
170 		return editorFactory;
171 	}
172 
173 	public static void setFileDialogs( XFileDialogs xFileDialogs )
174 	{
175 		fileDialogs = xFileDialogs;
176 	}
177 
178 	public static ToolHost getToolHost()
179 	{
180 		return toolHost;
181 	}
182 
183 	public static void setToolHost( ToolHost host )
184 	{
185 		toolHost = host;
186 	}
187 
188 	public static Frame getMainFrame()
189 	{
190 		return ( Frame )( frame instanceof Frame ? frame : null );
191 	}
192 
193 	public static JComboBox addTooltipListener( JComboBox combo, String defaultTooltip )
194 	{
195 		combo.setToolTipText( defaultTooltip );
196 		combo.addItemListener( new ItemListenerImplementation( combo, defaultTooltip ) );
197 
198 		return combo;
199 	}
200 
201 	public static Frame getParentFrame( Component component )
202 	{
203 		for( Container c = component.getParent(); c != null; c = c.getParent() )
204 		{
205 			if( c instanceof Frame )
206 				return ( Frame )c;
207 		}
208 		return getMainFrame();
209 	}
210 
211 	public static XDialogs getDialogs()
212 	{
213 		return dialogs;
214 	}
215 
216 	public static XFileDialogs getFileDialogs()
217 	{
218 		return fileDialogs;
219 	}
220 
221 	/***
222 	 * @deprecated use XForm related classes instead
223 	 */
224 
225 	@Deprecated
226 	public static ConfigurationDialog createConfigurationDialog( String name, String helpUrl, String description,
227 			ImageIcon icon )
228 	{
229 		return new SwingConfigurationDialogImpl( name, helpUrl, description, icon );
230 	}
231 
232 	/***
233 	 * @deprecated use XForm related classes instead
234 	 */
235 
236 	@Deprecated
237 	public static ConfigurationDialog createConfigurationDialog( String name, String helpUrl )
238 	{
239 		return new SwingConfigurationDialogImpl( name, helpUrl, null, null );
240 	}
241 
242 	/***
243 	 * @deprecated use XForm related classes instead
244 	 */
245 
246 	@Deprecated
247 	public static ConfigurationDialog createConfigurationDialog( String name )
248 	{
249 		return new SwingConfigurationDialogImpl( name, null, null, null );
250 	}
251 
252 	public static void showErrorMessage( String message )
253 	{
254 		if( message.length() > 120 )
255 		{
256 			dialogs.showExtendedInfo( "Error", "An error occurred", message, null );
257 		}
258 		else
259 		{
260 			dialogs.showErrorMessage( message );
261 		}
262 	}
263 
264 	public static boolean confirm( String question, String title )
265 	{
266 		return dialogs.confirm( question, title );
267 	}
268 
269 	public static int yesYesToAllOrNo( String question, String title )
270 	{
271 		return dialogs.yesYesToAllOrNo( question, title );
272 	}
273 
274 	public static String prompt( String question, String title, String value )
275 	{
276 		return dialogs.prompt( question, title, value );
277 	}
278 
279 	/***
280 	 * @deprecated use prompt(String question, String title, String value)
281 	 *             instead
282 	 */
283 
284 	@Deprecated
285 	public static String prompt( String question, String title )
286 	{
287 		return dialogs.prompt( question, title );
288 	}
289 
290 	public static boolean stopCellEditing( JTable table )
291 	{
292 		try
293 		{
294 			int column = table.getEditingColumn();
295 			if( column > -1 )
296 			{
297 				TableCellEditor cellEditor = table.getColumnModel().getColumn( column ).getCellEditor();
298 				if( cellEditor == null )
299 				{
300 					cellEditor = table.getDefaultEditor( table.getColumnClass( column ) );
301 				}
302 				if( cellEditor != null )
303 				{
304 					cellEditor.stopCellEditing();
305 				}
306 			}
307 		}
308 		catch( RuntimeException e )
309 		{
310 			return false;
311 		}
312 		return true;
313 	}
314 
315 	public static JPanel createProgressBarPanel( JProgressBar progressBar, int space, boolean indeterimate )
316 	{
317 		JPanel panel = new JPanel( new BorderLayout() );
318 
319 		progressBar.setValue( 0 );
320 		progressBar.setStringPainted( true );
321 		progressBar.setString( "" );
322 		progressBar.setIndeterminate( indeterimate );
323 
324 		progressBar.setBorder( BorderFactory.createMatteBorder( 0, 0, 1, 1, Color.LIGHT_GRAY ) );
325 
326 		panel.setBorder( BorderFactory.createEmptyBorder( space, space, space, space ) );
327 		panel.add( progressBar, BorderLayout.CENTER );
328 
329 		return panel;
330 	}
331 
332 	public static JSplitPane createHorizontalSplit()
333 	{
334 		JSplitPane splitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT );
335 		splitPane.setUI( new SoapUISplitPaneUI() );
336 		splitPane.setDividerSize( 10 );
337 		splitPane.setOneTouchExpandable( true );
338 		return splitPane;
339 	}
340 
341 	public static JSplitPane createHorizontalSplit( Component leftComponent, Component rightComponent )
342 	{
343 		JSplitPane splitPane = createHorizontalSplit();
344 
345 		splitPane.setLeftComponent( leftComponent );
346 		splitPane.setRightComponent( rightComponent );
347 		return splitPane;
348 	}
349 
350 	public static JSplitPane createVerticalSplit()
351 	{
352 		JSplitPane splitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT );
353 		splitPane.setUI( new SoapUISplitPaneUI() );
354 		splitPane.setDividerSize( 10 );
355 		splitPane.setOneTouchExpandable( true );
356 		splitPane.setBorder( null );
357 		return splitPane;
358 	}
359 
360 	public static JSplitPane createVerticalSplit( Component topComponent, Component bottomComponent )
361 	{
362 		JSplitPane splitPane = createVerticalSplit();
363 
364 		splitPane.setLeftComponent( topComponent );
365 		splitPane.setRightComponent( bottomComponent );
366 		return splitPane;
367 	}
368 
369 	public static void centerDialog( Window dialog )
370 	{
371 		centerDialog( dialog, dialog.getOwner() );
372 	}
373 
374 	public static void centerDialog( Window dialog, Window owner )
375 	{
376 		Dimension sz = dialog.getSize();
377 		Rectangle b = frame == null ? null : frame.getBounds();
378 
379 		if( owner != null && owner.isVisible() )
380 		{
381 			b = owner.getBounds();
382 		}
383 		else if( b == null )
384 		{
385 			GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
386 			b = ge.getDefaultScreenDevice().getDefaultConfiguration().getBounds();
387 		}
388 
389 		dialog.setLocation( ( int )( ( b.getWidth() - sz.getWidth() ) / 2 ) + ( int )b.getX(),
390 				( int )( ( b.getHeight() - sz.getHeight() ) / 2 ) + ( int )b.getY() );
391 	}
392 
393 	public static void showDialog( JDialog dialog )
394 	{
395 		centerDialog( dialog );
396 		dialog.setVisible( true );
397 	}
398 
399 	public static ImageIcon createImageIcon( String path )
400 	{
401 		if( StringUtils.isNullOrEmpty( path ) )
402 			return null;
403 
404 		if( isHeadless() )
405 			return null;
406 
407 		if( iconCache.containsKey( path ) )
408 			return iconCache.get( path );
409 
410 		String orgPath = path;
411 		java.net.URL imgURL = null;
412 
413 		try
414 		{
415 			if( path.indexOf( '/', 1 ) == -1 )
416 				path = "/com/eviware/soapui/resources/images" + path;
417 
418 			imgURL = SoapUI.class.getResource( path );
419 
420 			if( imgURL == null && path.endsWith( ".gif" ) )
421 			{
422 				imgURL = SoapUI.class.getResource( path.substring( 0, path.length() - 4 ) + ".png" );
423 			}
424 
425 			if( imgURL == null )
426 			{
427 				imgURL = loadFromSecondaryLoader( path );
428 			}
429 		}
430 		catch( Throwable t )
431 		{
432 			System.err.println( "Failed to find icon: " + t ); // FIXME
433 			// "Failed to find icon: java.lang.StackOverflowError"
434 			return null;
435 		}
436 
437 		if( imgURL != null )
438 		{
439 			try
440 			{
441 				ImageIcon imageIcon = new ImageIcon( imgURL );
442 				iconCache.put( orgPath, imageIcon );
443 				return imageIcon;
444 			}
445 			catch( Throwable e )
446 			{
447 				if( e instanceof NoClassDefFoundError )
448 					isHeadless = true;
449 				else
450 					System.err.println( "Failed to create icon: " + e );
451 
452 				return null;
453 			}
454 		}
455 		else
456 		{
457 			System.err.println( "Couldn't find icon file: " + path );
458 			return null;
459 		}
460 	}
461 
462 	public static boolean isHeadless()
463 	{
464 		if( isHeadless == null )
465 			isHeadless = GraphicsEnvironment.isHeadless();
466 
467 		return isHeadless.booleanValue();
468 	}
469 
470 	private static URL loadFromSecondaryLoader( String path )
471 	{
472 		for( ClassLoader loader : secondaryResourceLoaders )
473 		{
474 			URL url = loader.getResource( path );
475 			if( url != null )
476 			{
477 				return url;
478 			}
479 		}
480 		return null;
481 	}
482 
483 	public static void showInfoMessage( String message )
484 	{
485 		dialogs.showInfoMessage( message );
486 	}
487 
488 	public static void showInfoMessage( String message, String title )
489 	{
490 		dialogs.showInfoMessage( message, title );
491 	}
492 
493 	@SuppressWarnings( "unchecked" )
494 	public static <T extends Object> T prompt( String question, String title, T[] objects )
495 	{
496 		return ( T )dialogs.prompt( question, title, objects );
497 	}
498 
499 	@SuppressWarnings( "unchecked" )
500 	public static <T extends Object> T prompt( String question, String title, T[] objects, String value )
501 	{
502 		return ( T )dialogs.prompt( question, title, objects, value );
503 	}
504 
505 	public static JButton createToolbarButton( Action action )
506 	{
507 		JButton result = new JButton( action );
508 		result.setPreferredSize( TOOLBAR_BUTTON_DIMENSION );
509 		result.setText( "" );
510 		return result;
511 	}
512 
513 	public static JButton createToolbarButton( Action action, boolean enabled )
514 	{
515 		JButton result = createToolbarButton( action );
516 		result.setEnabled( enabled );
517 		return result;
518 	}
519 
520 	public static JPanel createTabPanel( JTabbedPane tabs, boolean addBorder )
521 	{
522 		GradientPanel panel = new GradientPanel( new BorderLayout() );
523 
524 		Color color = UIManager.getDefaults().getColor( "Panel.background" );
525 		Color darker = color.darker();
526 		panel.setForeground( new Color( ( color.getRed() + darker.getRed() ) / 2,
527 				( color.getGreen() + darker.getGreen() ) / 2, ( color.getBlue() + darker.getBlue() ) / 2 ) );
528 
529 		if( tabs.getTabPlacement() == JTabbedPane.LEFT || tabs.getTabPlacement() == JTabbedPane.RIGHT )
530 			panel.setDirection( GradientPanel.VERTICAL );
531 
532 		panel.add( tabs, BorderLayout.CENTER );
533 
534 		if( addBorder )
535 		{
536 			if( tabs.getTabPlacement() == JTabbedPane.TOP )
537 				panel.setBorder( BorderFactory.createMatteBorder( 1, 1, 0, 0, Color.GRAY ) );
538 			else
539 				panel.setBorder( BorderFactory.createMatteBorder( 0, 1, 0, 0, Color.GRAY ) );
540 		}
541 
542 		tabs.setBorder( null );
543 
544 		return panel;
545 	}
546 
547 	public static void showPopup( JPopupMenu popup, JComponent invoker, Point p )
548 	{
549 		popup.setInvoker( invoker );
550 
551 		popup.setLocation( ( int )( invoker.getLocationOnScreen().getX() + p.getX() ), ( int )( invoker
552 				.getLocationOnScreen().getY() + p.getY() ) );
553 		popup.setVisible( true );
554 	}
555 
556 	public static DesktopPanel selectAndShow( ModelItem modelItem )
557 	{
558 		UISupport.select( modelItem );
559 		return showDesktopPanel( modelItem );
560 	}
561 
562 	public static DesktopPanel showDesktopPanel( ModelItem modelItem )
563 	{
564 		if( modelItem == null )
565 			return null;
566 
567 		try
568 		{
569 			UISupport.setHourglassCursor();
570 			SoapUIDesktop desktop = SoapUI.getDesktop();
571 			return desktop == null ? null : desktop.showDesktopPanel( modelItem );
572 		}
573 		finally
574 		{
575 			UISupport.resetCursor();
576 		}
577 	}
578 
579 	public static DesktopPanel showDesktopPanel( DesktopPanel desktopPanel )
580 	{
581 		try
582 		{
583 			UISupport.setHourglassCursor();
584 			SoapUIDesktop desktop = SoapUI.getDesktop();
585 			return desktop == null ? null : desktop.showDesktopPanel( desktopPanel );
586 		}
587 		finally
588 		{
589 			UISupport.resetCursor();
590 		}
591 	}
592 
593 	public static Boolean confirmOrCancel( String question, String title )
594 	{
595 		return dialogs.confirmOrCancel( question, title );
596 	}
597 
598 	public static JPanel buildPanelWithToolbar( JComponent top, JComponent content )
599 	{
600 		JPanel p = new JPanel( new BorderLayout() );
601 		p.add( top, BorderLayout.NORTH );
602 		p.add( content, BorderLayout.CENTER );
603 
604 		return p;
605 	}
606 
607 	public static JPanel buildPanelWithToolbarAndStatusBar( JComponent top, JComponent content, JComponent bottom )
608 	{
609 		JPanel p = new JPanel( new BorderLayout() );
610 		p.add( top, BorderLayout.NORTH );
611 		p.add( content, BorderLayout.CENTER );
612 		p.add( bottom, BorderLayout.SOUTH );
613 
614 		return p;
615 	}
616 
617 	public static Dimension getPreferredButtonSize()
618 	{
619 		return TOOLBAR_BUTTON_DIMENSION;
620 	}
621 
622 	public static void showErrorMessage( Throwable ex )
623 	{
624 		SoapUI.logError( ex );
625 
626 		if( ex.toString().length() > 100 )
627 		{
628 			dialogs.showExtendedInfo( "Error", "An error of type " + ex.getClass().getSimpleName() + " occured.", ex
629 					.toString(), null );
630 		}
631 		else
632 		{
633 			dialogs.showErrorMessage( ex.toString() );
634 		}
635 	}
636 
637 	public static Component wrapInEmptyPanel( JComponent component, Border border )
638 	{
639 		JPanel panel = new JPanel( new BorderLayout() );
640 		panel.add( component, BorderLayout.CENTER );
641 		panel.setBorder( border );
642 
643 		return panel;
644 	}
645 
646 	public static boolean isWindows()
647 	{
648 		if( isWindows == null )
649 			isWindows = new Boolean( System.getProperty( "os.name" ).indexOf( "Windows" ) >= 0 );
650 
651 		return isWindows.booleanValue();
652 	}
653 
654 	public static boolean isMac()
655 	{
656 		if( isMac == null )
657 			isMac = new Boolean( System.getProperty( "os.name" ).indexOf( "Mac" ) >= 0 );
658 
659 		return isMac.booleanValue();
660 	}
661 
662 	public static void setHourglassCursor()
663 	{
664 		if( frame == null )
665 			return;
666 
667 		if( hourglassCursor == null )
668 			hourglassCursor = new Cursor( Cursor.WAIT_CURSOR );
669 
670 		frame.setCursor( hourglassCursor );
671 	}
672 
673 	public static void resetCursor()
674 	{
675 		if( frame == null )
676 			return;
677 
678 		if( defaultCursor == null )
679 			defaultCursor = new Cursor( Cursor.DEFAULT_CURSOR );
680 
681 		frame.setCursor( defaultCursor );
682 	}
683 
684 	public static void setUIUtils( UIUtils utils )
685 	{
686 		UISupport.uiUtils = utils;
687 	}
688 
689 	public static UIUtils getUIUtils()
690 	{
691 		return uiUtils;
692 	}
693 
694 	public static void invokeLater( Runnable runnable )
695 	{
696 		uiUtils.invokeLater( runnable );
697 	}
698 
699 	public static void invokeAndWait( Runnable runnable ) throws Exception
700 	{
701 		uiUtils.invokeAndWait( runnable );
702 	}
703 
704 	public static JXToolBar createToolbar()
705 	{
706 		JXToolBar toolbar = new JXToolBar();
707 		toolbar.addSpace( 1 );
708 		toolbar.setRollover( true );
709 		toolbar.putClientProperty( Options.HEADER_STYLE_KEY, HeaderStyle.SINGLE );
710 		toolbar.setBorder( BorderFactory.createEmptyBorder( 3, 0, 3, 0 ) );
711 		toolbar.setMinimumSize( new Dimension( 20, 20 ) );
712 		return toolbar;
713 	}
714 
715 	public static JXToolBar createSmallToolbar()
716 	{
717 		JXToolBar toolbar = new JXToolBar();
718 		toolbar.addSpace( 1 );
719 		toolbar.setRollover( true );
720 		toolbar.putClientProperty( Options.HEADER_STYLE_KEY, HeaderStyle.SINGLE );
721 		toolbar.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
722 		toolbar.setMinimumSize( new Dimension( 20, 20 ) );
723 		return toolbar;
724 	}
725 
726 	/***
727 	 * Replaces "menu" in the keyStroke with ctrl or meta depending on
728 	 * getMenuShortcutKeyMask
729 	 */
730 
731 	public static KeyStroke getKeyStroke( String keyStroke )
732 	{
733 		try
734 		{
735 			if( InputHandler.getMenuShortcutKeyMask() == Event.META_MASK )
736 			{
737 				keyStroke = keyStroke.replaceAll( "menu", "meta" );
738 			}
739 			else
740 			{
741 				keyStroke = keyStroke.replaceAll( "menu", "ctrl" );
742 			}
743 		}
744 		catch( Throwable e )
745 		{
746 			keyStroke = keyStroke.replaceAll( "menu", "ctrl" );
747 		}
748 
749 		return KeyStroke.getKeyStroke( keyStroke );
750 	}
751 
752 	public static DescriptionPanel buildDescription( String title, String string, ImageIcon icon )
753 	{
754 		return new DescriptionPanel( title, string, icon );
755 	}
756 
757 	public static void setPreferredHeight( Component component, int heigth )
758 	{
759 		component.setPreferredSize( new Dimension( ( int )component.getPreferredSize().getWidth(), heigth ) );
760 	}
761 
762 	public static JButtonBar initDialogActions( ActionList actions, final JDialog dialog )
763 	{
764 		return initWindowActions( actions, dialog.getRootPane(), dialog );
765 	}
766 
767 	public static JButtonBar initFrameActions( ActionList actions, final JFrame frame )
768 	{
769 		return initWindowActions( actions, frame.getRootPane(), frame );
770 	}
771 
772 	private static JButtonBar initWindowActions( ActionList actions, JRootPane rootPane, final Window dialog )
773 	{
774 		rootPane.getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).put(
775 				KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ), "ESCAPE" );
776 		rootPane.getActionMap().put( "ESCAPE", new AbstractAction()
777 		{
778 			public void actionPerformed( ActionEvent e )
779 			{
780 				dialog.setVisible( false );
781 			}
782 		} );
783 
784 		if( actions != null )
785 		{
786 			JButtonBar buttons = new JButtonBar();
787 			buttons.addActions( actions );
788 			rootPane.setDefaultButton( buttons.getDefaultButton() );
789 
790 			for( int c = 0; c < actions.getActionCount(); c++ )
791 			{
792 				Action action = actions.getActionAt( c );
793 				if( action instanceof HelpActionMarker )
794 				{
795 					rootPane.getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).put(
796 							KeyStroke.getKeyStroke( KeyEvent.VK_F1, 0 ), "HELP" );
797 					rootPane.getActionMap().put( "HELP", action );
798 					break;
799 				}
800 			}
801 
802 			return buttons;
803 		}
804 
805 		return null;
806 	}
807 
808 	public static void initDialogActions( final JDialog dialog, Action helpAction, JButton defaultButton )
809 	{
810 		dialog.getRootPane().getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).put(
811 				KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ), "ESCAPE" );
812 		dialog.getRootPane().getActionMap().put( "ESCAPE", new AbstractAction()
813 		{
814 			public void actionPerformed( ActionEvent e )
815 			{
816 				dialog.setVisible( false );
817 			}
818 		} );
819 
820 		if( defaultButton != null )
821 			dialog.getRootPane().setDefaultButton( defaultButton );
822 
823 		if( helpAction != null )
824 		{
825 			dialog.getRootPane().getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).put(
826 					KeyStroke.getKeyStroke( KeyEvent.VK_F1, 0 ), "HELP" );
827 			dialog.getRootPane().getActionMap().put( "HELP", helpAction );
828 		}
829 	}
830 
831 	public static <T extends JComponent> T addTitledBorder( T component, String title )
832 	{
833 		component.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ),
834 				BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEmptyBorder(),
835 						title ), component.getBorder() ) ) );
836 
837 		return component;
838 	}
839 
840 	public static void beep()
841 	{
842 		Toolkit.getDefaultToolkit().beep();
843 	}
844 
845 	@SuppressWarnings( "unchecked" )
846 	public static <T extends Object> T prompt( String question, String title, List<T> objects )
847 	{
848 		return ( T )dialogs.prompt( question, title, objects.toArray() );
849 	}
850 
851 	@SuppressWarnings( "unchecked" )
852 	public static <T extends Object> T prompt( String question, String title, List<T> objects, String value )
853 	{
854 		return ( T )dialogs.prompt( question, title, objects.toArray(), value );
855 	}
856 
857 	public static void showExtendedInfo( String title, String description, String content, Dimension size )
858 	{
859 		dialogs.showExtendedInfo( title, description, content, size );
860 	}
861 
862 	public static boolean confirmExtendedInfo( String title, String description, String content, Dimension size )
863 	{
864 		return dialogs.confirmExtendedInfo( title, description, content, size );
865 	}
866 
867 	public static Boolean confirmOrCancelExtendedInfo( String title, String description, String content, Dimension size )
868 	{
869 		return dialogs.confirmOrCancleExtendedInfo( title, description, content, size );
870 	}
871 
872 	public static void select( ModelItem modelItem )
873 	{
874 		if( SoapUI.getNavigator() != null )
875 			SoapUI.getNavigator().selectModelItem( modelItem );
876 	}
877 
878 	public static JButton createActionButton( Action action, boolean enabled )
879 	{
880 		JButton button = createToolbarButton( action, enabled );
881 		action.putValue( Action.NAME, null );
882 		return button;
883 	}
884 
885 	public static URL findSplash( String filename )
886 	{
887 		File file = new File( filename );
888 		URL url = null;
889 
890 		try
891 		{
892 			if( !file.exists() )
893 				url = SoapUI.class.getResource( "/com/eviware/soapui/resources/images/" + filename );
894 			else
895 				url = file.toURI().toURL();
896 		}
897 		catch( Exception e1 )
898 		{
899 		}
900 
901 		try
902 		{
903 			if( url == null )
904 				url = new URL( "http://www.soapui.org/images/" + filename );
905 		}
906 		catch( Exception e2 )
907 		{
908 			SoapUI.logError( e2 );
909 		}
910 
911 		return url;
912 	}
913 
914 	public static String selectXPath( String title, String info, String xml, String xpath )
915 	{
916 		return dialogs.selectXPath( title, info, xml, xpath );
917 	}
918 
919 	public static PreviewCorner addPreviewCorner( JScrollPane scrollPane, boolean forceScrollbars )
920 	{
921 		ImageIcon previewIcon = UISupport.createImageIcon( "/previewscroller.gif" );
922 		PreviewCorner previewCorner = new PreviewCorner( scrollPane, previewIcon, true, JScrollPane.LOWER_RIGHT_CORNER );
923 		scrollPane.setCorner( JScrollPane.LOWER_RIGHT_CORNER, previewCorner );
924 
925 		if( forceScrollbars )
926 		{
927 			scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS );
928 			scrollPane.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS );
929 		}
930 
931 		return previewCorner;
932 	}
933 
934 	public static <T extends JComponent> T setFixedSize( T component, Dimension size )
935 	{
936 		component.setMinimumSize( size );
937 		component.setMaximumSize( size );
938 		component.setPreferredSize( size );
939 		component.setSize( size );
940 
941 		return component;
942 	}
943 
944 	public static <T extends JComponent> T setFixedSize( T component, int i, int j )
945 	{
946 		return setFixedSize( component, new Dimension( i, j ) );
947 	}
948 
949 	public static void setFixedColumnSize( TableColumn column, int width )
950 	{
951 		column.setWidth( width );
952 		column.setPreferredWidth( width );
953 		column.setMaxWidth( width );
954 		column.setMinWidth( width );
955 	}
956 
957 	public static JButton createToolbarButton( ImageIcon icon )
958 	{
959 		JButton result = new JButton( icon );
960 		result.setPreferredSize( TOOLBAR_BUTTON_DIMENSION );
961 		return result;
962 	}
963 
964 	public static Font getEditorFont()
965 	{
966 		return getEditorFont( SoapUI.getSettings() );
967 	}
968 
969 	public static Font getEditorFont( Settings settings )
970 	{
971 		String editorFont = settings.getString( UISettings.EDITOR_FONT, null );
972 		if( StringUtils.hasContent( editorFont ) )
973 			return Font.decode( editorFont );
974 
975 		Integer fontSize = ( Integer )UIManager.get( "customFontSize" );
976 		if( fontSize == null )
977 		{
978 			fontSize = DEFAULT_EDITOR_FONT_SIZE;
979 		}
980 
981 		return Font.decode( DEFAULT_EDITOR_FONT + " " + fontSize );
982 	}
983 
984 	public static char[] promptPassword( String question, String title )
985 	{
986 		return dialogs.promptPassword( question, title );
987 	}
988 
989 	private static final class ItemListenerImplementation implements ItemListener
990 	{
991 		private final JComboBox combo;
992 		private final String defaultTooltip;
993 
994 		public ItemListenerImplementation( JComboBox combo, String defaultTooltip )
995 		{
996 			this.combo = combo;
997 			this.defaultTooltip = defaultTooltip;
998 		}
999 
1000 		// set tooltip, property is set by model directly
1001 		public void itemStateChanged( ItemEvent e )
1002 		{
1003 			Object item = combo.getSelectedItem();
1004 			if( item == null )
1005 			{
1006 				combo.setToolTipText( defaultTooltip );
1007 			}
1008 			else
1009 			{
1010 				String selectedItem = item.toString();
1011 
1012 				if( item instanceof ModelItem )
1013 					selectedItem = ( ( ModelItem )item ).getName();
1014 				else if( item instanceof TestProperty )
1015 					selectedItem = ( ( TestProperty )item ).getName();
1016 
1017 				combo.setToolTipText( selectedItem );
1018 			}
1019 		}
1020 	}
1021 
1022 	public static boolean isIdePlugin()
1023 	{
1024 		return SoapUI.getSoapUICore() instanceof SwingPluginSoapUICore;
1025 	}
1026 
1027 	public static JPanel createEmptyPanel( int top, int left, int bottom, int right )
1028 	{
1029 		JPanel panel = new JPanel( new BorderLayout() );
1030 		panel.setBorder( BorderFactory.createEmptyBorder( top, left, bottom, right ) );
1031 		return panel;
1032 	}
1033 }