View Javadoc

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