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.components;
14  
15  import com.eviware.soapui.support.swing.JTextComponentPopupMenu;
16  import com.jgoodies.forms.layout.CellConstraints;
17  import com.jgoodies.forms.layout.FormLayout;
18  import com.jgoodies.forms.layout.RowSpec;
19  
20  import javax.swing.*;
21  import javax.swing.border.Border;
22  import javax.swing.text.JTextComponent;
23  import java.awt.*;
24  import java.awt.event.ComponentAdapter;
25  import java.awt.event.ComponentEvent;
26  import java.util.HashMap;
27  import java.util.Iterator;
28  import java.util.Map;
29  
30  /***
31   * Utility-class for creating forms
32   */
33  
34  public class SimpleForm
35  {
36     private JPanel panel;
37     private CellConstraints cc = new CellConstraints();
38     private FormLayout layout;
39     private RowSpec rowSpec;
40     private int rowSpacing = 5;
41     private Map<String,JComponent> components = new HashMap<String,JComponent>();
42     private Map<JComboBox,Object[]> comboBoxMaps = new HashMap<JComboBox,Object[]>();
43     private String rowAlignment = "top";
44     private Map<String,String> hiddenValues;
45  	private boolean appended;
46  	private Font labelFont;
47     private int defaultTextAreaColumns = 30;
48     private int defaultTextAreaRows = 3;
49     private int defaultTextFieldColumns = 30;
50  
51     public SimpleForm()
52     {
53        this( 5 );
54     }
55     
56     public SimpleForm( String layout )
57     {
58        this( new FormLayout( layout ) );
59     }
60  
61     public SimpleForm( FormLayout layout )
62     {
63        this.layout = layout;
64        panel = new JPanel( layout );
65        rowSpec = new RowSpec( rowAlignment + ":pref" );
66     }
67  
68     public SimpleForm( int indent )
69  	{
70     	 this( indent + "px:none,left:pref,10px,left:default,5px:grow(1.0)" );
71  	}
72  
73  	public JPanel getPanel()
74     {
75        return panel;
76     }
77  
78     public String getRowAlignment()
79     {
80        return rowAlignment;
81     }
82  
83     public Font getLabelFont()
84  	{
85  		return labelFont;
86  	}
87  
88  	public void setLabelFont( Font labelFont )
89  	{
90  		this.labelFont = labelFont;
91  	}
92  
93  	public void setRowAlignment( String rowAlignment )
94     {
95        this.rowAlignment = rowAlignment;
96        rowSpec = new RowSpec( rowAlignment + ":pref" );
97     }
98  
99     public int getRowSpacing()
100    {
101       return rowSpacing;
102    }
103 
104    public void setRowSpacing( int rowSpacing )
105    {
106       this.rowSpacing = rowSpacing;
107    }
108 
109    public void addHiddenValue( String name, String value )
110    {
111       if( hiddenValues == null )
112          hiddenValues = new HashMap<String,String>();
113 
114       hiddenValues.put( name, value );
115    }
116 
117    public JButton addRightButton( Action action )
118    {
119       if( rowSpacing > 0 && !components.isEmpty() )
120          addSpace( rowSpacing );
121 
122       layout.appendRow( rowSpec );
123       int row = layout.getRowCount();
124 
125       JButton button = new JButton( action );
126       panel.add( button, cc.xy( 4, row, "right,bottom" ) );
127       return button;
128    }
129 
130    public void addSpace()
131    {
132    	addSpace( rowSpacing );
133    }
134    
135    public void addSpace( int size )
136    {
137       if( size > 0 )
138          layout.appendRow( new RowSpec( size + "px" ) );
139    }
140 
141    public void addRightComponent( JComponent component )
142    {
143       if( rowSpacing > 0 && !components.isEmpty() )
144          addSpace( rowSpacing );
145 
146       layout.appendRow( rowSpec );
147       int row = layout.getRowCount();
148 
149       panel.add( component, cc.xy( 4, row, "right,bottom" ) );
150    }
151 
152    public JCheckBox appendCheckBox( String caption, String label, boolean selected )
153    {
154       JCheckBox checkBox = new JCheckBox( label, selected );
155       checkBox.getAccessibleContext().setAccessibleDescription( caption );
156       components.put( caption, checkBox );
157       append( caption, checkBox );
158       return checkBox;
159    }
160 
161 //   public <T extends JComponent> T append( String label, T component )
162 
163    public void append( String label, JComponent component )
164    {
165       append( label, component, null );
166    }
167 
168    public JComboBox appendComboBox( String label, Map<?,?> values )
169    {
170       Object[] valueArray = new Object[values.size()];
171       Object[] keyArray = new Object[values.size()];
172 
173       int ix = 0;
174       for( Iterator<?> i = values.keySet().iterator(); i.hasNext(); ix++ )
175       {
176          keyArray[ix] = i.next();
177          valueArray[ix] = values.get( keyArray[ix] );
178       }
179 
180       JComboBox comboBox = new JComboBox( valueArray );
181 
182       comboBoxMaps.put( comboBox, keyArray );
183 
184       append( label, comboBox );
185       return comboBox;
186    }
187 
188    public JComboBox appendComboBox( String label, Object [] values, String tooltip )
189    {
190       JComboBox comboBox = new JComboBox( values );
191       comboBox.setToolTipText( tooltip );
192       comboBox.getAccessibleContext().setAccessibleDescription( tooltip );
193       append( label, comboBox );
194       return comboBox;
195    }
196    
197    public JComboBox appendComboBox( String label, ComboBoxModel model, String tooltip )
198    {
199       JComboBox comboBox = new JComboBox( model );
200       comboBox.setToolTipText( tooltip );
201       comboBox.getAccessibleContext().setAccessibleDescription( tooltip );
202       append( label, comboBox );
203       return comboBox;
204    }
205 
206    public void appendFixed( String label, JComponent component )
207    {
208       append( label, component, "left:pref" );
209    }
210    
211    public  <T extends JComponent> T append( String label, T component, String alignments )
212    {
213    	JLabel jlabel = null;
214    	if( label != null )
215    	{
216    		jlabel = new JLabel( label.endsWith(":") ? label : label + ":" );
217          jlabel.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ) );
218          if( labelFont != null )
219          	jlabel.setFont( labelFont );
220    	}
221    	
222    	return append( label, jlabel, component, alignments );
223    }
224    
225    public <T extends JComponent> T append( String name, JComponent label, T component, String alignments )
226    {
227    	int spaceRowIndex = -1;
228    	
229       if( rowSpacing > 0 && appended )
230       {
231          addSpace( rowSpacing );
232          spaceRowIndex = layout.getRowCount();
233       }
234 
235       layout.appendRow( rowSpec );
236       int row = layout.getRowCount();
237 
238       if( label != null )
239       {
240 			panel.add( label, cc.xy( 2, row ) );
241 			component.addComponentListener( new LabelHider( label, spaceRowIndex ) );
242 			
243 			if( label instanceof JLabel )
244 			{
245 				JLabel jl = ((JLabel)label);
246 				jl.setLabelFor( component );
247 				String text = jl.getText();
248 				int ix = text.indexOf( '&' );
249 				if( ix >= 0 )
250 				{
251 					jl.setText( text.substring( 0, ix ) + text.substring( ix+1 ) );
252 					jl.setDisplayedMnemonicIndex( ix );
253 					jl.setDisplayedMnemonic( text.charAt( ix+1 ) );
254 				}
255 				
256 				if( component.getAccessibleContext() != null )
257 					component.getAccessibleContext().setAccessibleName( text );
258 			}
259       }
260       else
261       	component.addComponentListener( new LabelHider( null, spaceRowIndex ) );
262 
263       if( alignments == null )
264          panel.add( component, cc.xy( 4, row ) );
265       else
266          panel.add( component, cc.xy( 4, row, alignments ) );
267 
268       components.put( name, component );
269       appended = true;
270       
271       return component;
272    }
273 
274    public boolean hasComponents()
275    {
276       return !components.isEmpty();
277    }
278 
279    public void appendSeparator()
280    {
281    	if( appended && rowSpacing > 0 )
282    		addSpace( rowSpacing );
283 
284       layout.appendRow( rowSpec );
285       int row = layout.getRowCount();
286 
287       panel.add( new JSeparator(), cc.xywh( 2, row, 3, 1 ) );
288       appended = true;
289    }
290 
291    public JTextField appendTextField( String label, String tooltip )
292    {
293       JTextField textField = new JUndoableTextField();
294       textField.setColumns( defaultTextFieldColumns );
295       textField.setToolTipText( tooltip );
296       textField.getAccessibleContext().setAccessibleDescription( tooltip );
297       JTextComponentPopupMenu.add( textField );
298 		append( label, textField );
299 		return textField;
300    }
301    
302    public JTextArea appendTextArea( String label, String tooltip )
303    {
304       JTextArea textArea = new JUndoableTextArea();
305       textArea.setColumns( defaultTextAreaColumns );
306       textArea.setRows( defaultTextAreaRows );
307       textArea.setAutoscrolls(true);
308       textArea.add(new JScrollPane());
309       textArea.setToolTipText( tooltip );
310       textArea.getAccessibleContext().setAccessibleDescription( tooltip );
311       JTextComponentPopupMenu.add( textArea );
312 		append( label, new JScrollPane( textArea ));
313 		return textArea;
314    }
315 
316    public int getDefaultTextAreaColumns()
317    {
318       return defaultTextAreaColumns;
319    }
320 
321    public void setDefaultTextAreaColumns( int defaultTextAreaColumns )
322    {
323       this.defaultTextAreaColumns = defaultTextAreaColumns;
324    }
325 
326    public int getDefaultTextAreaRows()
327    {
328       return defaultTextAreaRows;
329    }
330 
331    public void setDefaultTextAreaRows( int defaultTextAreaRows )
332    {
333       this.defaultTextAreaRows = defaultTextAreaRows;
334    }
335 
336    public JPasswordField appendPasswordField( String label, String tooltip )
337    {
338       JPasswordField textField = new JPasswordField();
339       textField.setColumns( 30 );
340       textField.setToolTipText( tooltip );
341       textField.getAccessibleContext().setAccessibleDescription( tooltip );
342 		append( label, textField );
343 		return textField;
344    }
345 
346    public void setComponentValue( String label, String value )
347    {
348       JComponent component = getComponent( label );
349 
350       if( component instanceof JTextComponent )
351       {
352          ((JTextComponent) component).setText( value );
353       }
354       else if( component instanceof JComboBox )
355       {
356          JComboBox comboBox = ((JComboBox) component);
357          comboBox.setSelectedItem( value );
358       }
359       else if( component instanceof JList )
360       {
361          ((JList) component).setSelectedValue( value, true );
362       }
363       else if( component instanceof JCheckBox )
364       {
365          ((JCheckBox) component).setSelected( Boolean.valueOf( value ));
366       }
367       else if( component instanceof JFormComponent )
368       {
369       	((JFormComponent) component).setValue( value );
370       }      	
371    }
372    
373    public String getComponentValue( String label )
374    {
375       JComponent component = getComponent( label );
376       if( component == null )
377       {
378          return (String) (hiddenValues == null ? null : hiddenValues.get( label ));
379       }
380       
381       if( component instanceof JTextComponent )
382       {
383          return ((JTextComponent) component).getText();
384       }
385 
386       if( component instanceof JComboBox )
387       {
388          JComboBox comboBox = ((JComboBox) component);
389          int selectedIndex = comboBox.getSelectedIndex();
390          if( selectedIndex != -1 )
391          {
392 	         if( comboBoxMaps.containsKey( component ) )
393 	         {
394 	            Object[] keys = (Object[]) comboBoxMaps.get( comboBox );
395 	            Object value = keys[selectedIndex];
396 					return (String) value == null ? null : value.toString(); // Added support for enums
397 	         }
398 	         else
399 	         {
400 	            Object value = comboBox.getSelectedItem();
401 	            return (String) value == null ? null : value.toString(); // Added support for enums
402 	         }
403          }
404       }
405 
406       if( component instanceof JList )
407       {
408          return (String) ((JList) component).getSelectedValue();
409       }
410 
411       if( component instanceof JCheckBox )
412       {
413          return String.valueOf( ((JCheckBox) component).isSelected() );
414       }
415 
416       else if( component instanceof JFormComponent )
417       {
418       	return ((JFormComponent) component).getValue();
419       }      	
420       
421       return null;
422    }
423 
424    public JComponent getComponent( String label )
425    {
426       return (JComponent) components.get( label );
427    }
428 
429 	public void setBorder(Border border)
430 	{
431 		panel.setBorder( border );
432 	}
433 
434 	public int getRowCount()
435 	{
436 		return layout.getRowCount();
437 	}
438 	
439 	public void addComponent(JComponent component)
440 	{
441 		layout.appendRow( rowSpec );
442       int row = layout.getRowCount();
443 		
444 		panel.add( component, cc.xyw( 2, row, 4 ) );
445 	}
446 
447 	public void setValues(Map<String, String> values)
448 	{
449 		for( Iterator<String> i = values.keySet().iterator(); i.hasNext(); )
450 		{
451 			String key = i.next();
452 			setComponentValue( key, values.get( key ));
453 		}
454 	}
455 
456 	public void getValues(Map<String, String> values)
457 	{
458 		for( Iterator<String> i = components.keySet().iterator(); i.hasNext(); )
459 		{
460 			String key = i.next();
461 			values.put( key, getComponentValue( key ));
462 		}
463 	}
464 
465 	public void append( JComponent component )
466 	{
467 		int spaceRowIndex = -1;
468    	
469       if( rowSpacing > 0 && appended )
470       {
471          addSpace( rowSpacing );
472          spaceRowIndex = layout.getRowCount();
473       }
474 
475       layout.appendRow( rowSpec );
476       int row = layout.getRowCount();
477 
478       panel.add( component, cc.xyw( 2, row, 4 ) );
479       
480       component.addComponentListener( new LabelHider( null, spaceRowIndex ) );
481       
482       appended = true;
483 	}
484 
485    public void setDefaultTextFieldColumns( int defaultTextFieldColumns )
486    {
487       this.defaultTextFieldColumns = defaultTextFieldColumns;
488    }
489 
490    private final class LabelHider extends ComponentAdapter
491 	{
492 		private final JComponent jlabel;
493 		private final int rowIndex;
494 
495 		public LabelHider( JComponent label, int i )
496 		{
497 			this.jlabel = label;
498 			this.rowIndex = i;
499 		}
500 
501 		public void componentHidden( ComponentEvent e )
502 		{
503 			if( jlabel != null )
504 				jlabel.setVisible( false );
505 			
506 			if( rowIndex >= 0 && rowIndex < layout.getRowCount() )
507 				layout.setRowSpec( rowIndex, new RowSpec( "0px" ));
508 		}
509 
510 		public void componentShown( ComponentEvent e )
511 		{
512 			if( jlabel != null )
513 				jlabel.setVisible( true );
514 			
515 			if( rowIndex >= 0 && rowIndex < layout.getRowCount() )
516 				layout.setRowSpec( rowIndex, new RowSpec( rowSpacing + "px" ));
517 		}
518 	}
519 
520 	public <T extends JComponent> T  append( String name, JLabel label, T field )
521 	{
522 		return append( name, label, field, null );
523 	}
524 
525    public void setEnabled( boolean b )
526    {
527       for( JComponent component : components.values())
528       {
529          if( component instanceof JScrollPane )
530             ((JScrollPane)component).getViewport().getView().setEnabled( b );
531 
532          component.setEnabled( b );
533       }
534    }
535 }
536