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