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