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