View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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 java.awt.BorderLayout;
16  import java.awt.CardLayout;
17  import java.awt.Color;
18  import java.awt.Dimension;
19  import java.awt.event.ActionEvent;
20  import java.beans.PropertyChangeEvent;
21  import java.beans.PropertyChangeListener;
22  import java.util.ArrayList;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  
27  import javax.swing.AbstractAction;
28  import javax.swing.BorderFactory;
29  import javax.swing.JComponent;
30  import javax.swing.JPanel;
31  import javax.swing.JSplitPane;
32  import javax.swing.JToggleButton;
33  import javax.swing.JToolBar;
34  import javax.swing.SwingConstants;
35  
36  import com.jgoodies.looks.HeaderStyle;
37  import com.jgoodies.looks.Options;
38  
39  public class JInspectorPanelImpl extends JPanel implements PropertyChangeListener, JInspectorPanel
40  {
41  	private float defaultDividerLocation = 0.7F;
42  
43  	private final JSplitPane mainSplit;
44  	private JPanel inspectorPanel;
45  	private int lastDividerLocation = 0;
46  	private JXToolBar inspectToolbar;
47  	private List<Inspector> inspectors = new ArrayList<Inspector>();
48  	private Map<Inspector, JToggleButton> inspectorButtons = new HashMap<Inspector, JToggleButton>();
49  	public Inspector currentInspector;
50  
51  	private final int orientation;
52  
53  	public JInspectorPanelImpl( JComponent contentComponent )
54  	{
55  		this( contentComponent, SwingConstants.BOTTOM );
56  	}
57  
58  	public JInspectorPanelImpl( JComponent contentComponent, int orientation )
59  	{
60  		super( new BorderLayout() );
61  		this.orientation = orientation;
62  
63  		inspectorPanel = new JPanel( new CardLayout() );
64  		inspectorPanel.setVisible( false );
65  
66  		mainSplit = new JSplitPane(
67  				orientation == SwingConstants.LEFT || orientation == SwingConstants.RIGHT ? JSplitPane.HORIZONTAL_SPLIT
68  						: JSplitPane.VERTICAL_SPLIT );
69  		mainSplit.setDividerSize( 5 );
70  		mainSplit.setBorder( null );
71  		mainSplit.setOneTouchExpandable( false );
72  
73  		JXToolBar toolbar = createInspectButtons();
74  		if( orientation == SwingConstants.BOTTOM )
75  		{
76  			mainSplit.setTopComponent( contentComponent );
77  			mainSplit.setBottomComponent( inspectorPanel );
78  			mainSplit.setResizeWeight( 0.8 );
79  			toolbar.setBorder( BorderFactory.createEmptyBorder( 1, 2, 3, 2 ) );
80  			add( toolbar, BorderLayout.SOUTH );
81  		}
82  		else if( orientation == SwingConstants.LEFT )
83  		{
84  			mainSplit.setRightComponent( contentComponent );
85  
86  			JPanel p = new JPanel( new BorderLayout() );
87  			p.add( toolbar );
88  			toolbar.setBorder( BorderFactory.createEmptyBorder( 2, 3, 0, 4 ) );
89  			mainSplit.setLeftComponent( inspectorPanel );
90  			mainSplit.setResizeWeight( 0.2 );
91  
92  			toolbar.setOrientation( JToolBar.VERTICAL );
93  
94  			add( p, BorderLayout.WEST );
95  		}
96  		else if( orientation == SwingConstants.RIGHT )
97  		{
98  			mainSplit.setLeftComponent( contentComponent );
99  
100 			JPanel p = new JPanel( new BorderLayout() );
101 			p.add( toolbar );
102 			toolbar.setBorder( BorderFactory.createEmptyBorder( 2, 1, 0, 3 ) );
103 			mainSplit.setRightComponent( inspectorPanel );
104 			mainSplit.setResizeWeight( 0.8 );
105 			toolbar.setOrientation( JToolBar.VERTICAL );
106 			add( p, BorderLayout.EAST );
107 		}
108 
109 		add( mainSplit, BorderLayout.CENTER );
110 	}
111 
112 	private JXToolBar createInspectButtons()
113 	{
114 		inspectToolbar = new JXToolBar()
115 		{
116 			@Override
117 			public Dimension getMinimumSize()
118 			{
119 				return new Dimension( 10, 10 );
120 			}
121 		};
122 
123 		inspectToolbar.setRollover( true );
124 		inspectToolbar.putClientProperty( Options.HEADER_STYLE_KEY, HeaderStyle.SINGLE );
125 		inspectToolbar.setBorder( BorderFactory.createEmptyBorder( 3, 0, 3, 0 ) );
126 
127 		if( orientation == SwingConstants.TOP || orientation == SwingConstants.BOTTOM )
128 			inspectToolbar.addSpace( 10 );
129 		inspectToolbar.setBackground( Color.WHITE );
130 		inspectToolbar.setOpaque( true );
131 		return inspectToolbar;
132 	}
133 
134 	public float getDefaultDividerLocation()
135 	{
136 		return defaultDividerLocation;
137 	}
138 
139 	public void setDefaultDividerLocation( float defaultDividerLocation )
140 	{
141 		this.defaultDividerLocation = defaultDividerLocation;
142 		setResetDividerLocation();
143 	}
144 
145 	public <T extends Inspector> T addInspector( final T inspector )
146 	{
147 		if( inspectors.size() > 0 )
148 		{
149 			inspectToolbar.addSpace( 5 );
150 		}
151 
152 		inspectors.add( inspector );
153 		inspector.addPropertyChangeListener( JInspectorPanelImpl.this );
154 
155 		inspectorPanel.add( inspector.getComponent(), inspector.getInspectorId() );
156 		JToggleButton button = new JToggleButton( new SelectInspectorAction( inspector ) );
157 
158 		inspectorButtons.put( inspector, button );
159 		if( orientation == SwingConstants.LEFT )
160 		{
161 			String text = button.getText();
162 			button.setText( null );
163 			button.setPreferredSize( new Dimension( 17, 10 ) );
164 			button.setIcon( new VTextIcon( inspectToolbar, text, VTextIcon.ROTATE_LEFT ) );
165 			inspectToolbar.add( button );
166 		}
167 		else if( orientation == SwingConstants.RIGHT )
168 		{
169 			String text = button.getText();
170 			button.setText( null );
171 			button.setPreferredSize( new Dimension( 17, 10 ) );
172 			button.setIcon( new VTextIcon( inspectToolbar, text, VTextIcon.ROTATE_RIGHT ) );
173 			inspectToolbar.add( button );
174 		}
175 		else
176 			inspectToolbar.add( button );
177 
178 		button.setMinimumSize( new Dimension( 10, 10 ) );
179 
180 		inspectToolbar.invalidate();
181 		repaint();
182 
183 		return inspector;
184 	}
185 
186 	public Inspector getInspector( String inspectorId )
187 	{
188 		for( Inspector inspector : inspectors )
189 		{
190 			if( inspector.getInspectorId().equals( inspectorId ) )
191 				return inspector;
192 		}
193 
194 		return null;
195 	}
196 
197 	public Inspector getInspectorByTitle( String title )
198 	{
199 		for( Inspector inspector : inspectors )
200 		{
201 			if( inspector.getTitle().equals( title ) )
202 				return inspector;
203 		}
204 
205 		return null;
206 	}
207 
208 	public void propertyChange( PropertyChangeEvent evt )
209 	{
210 		if( evt.getPropertyName().equals( Inspector.ENABLED_PROPERTY ) )
211 		{
212 			JToggleButton toggleButton = inspectorButtons.get( evt.getSource() );
213 			if( toggleButton != null )
214 				toggleButton.setEnabled( ( Boolean )evt.getNewValue() );
215 		}
216 	}
217 
218 	public JComponent getComponent()
219 	{
220 		return this;
221 	}
222 
223 	public class SelectInspectorAction extends AbstractAction implements PropertyChangeListener
224 	{
225 		private final Inspector inspector;
226 
227 		public SelectInspectorAction( Inspector inspector )
228 		{
229 			super( inspector.getTitle() );
230 			this.inspector = inspector;
231 
232 			putValue( AbstractAction.SHORT_DESCRIPTION, inspector.getDescription() );
233 			putValue( AbstractAction.SMALL_ICON, inspector.getIcon() );
234 			setEnabled( inspector.isEnabled() );
235 
236 			inspector.addPropertyChangeListener( this );
237 		}
238 
239 		public void actionPerformed( ActionEvent arg0 )
240 		{
241 			JToggleButton button = inspectorButtons.get( inspector );
242 			if( !button.isSelected() )
243 			{
244 				deactivate();
245 				// currentInspector = null;
246 				// button.setBackground( inspectToolbar.getBackground() );
247 				// lastDividerLocation = mainSplit.getDividerLocation();
248 				// inspectorPanel.setVisible( false );
249 			}
250 			else
251 			{
252 				activate( inspector );
253 			}
254 		}
255 
256 		public void propertyChange( PropertyChangeEvent evt )
257 		{
258 			if( evt.getPropertyName().equals( Inspector.TITLE_PROPERTY ) )
259 				putValue( AbstractAction.NAME, evt.getNewValue() );
260 			else if( evt.getPropertyName().equals( Inspector.ICON_PROPERTY ) )
261 				putValue( AbstractAction.SMALL_ICON, evt.getNewValue() );
262 			else if( evt.getPropertyName().equals( Inspector.DESCRIPTION_PROPERTY ) )
263 				putValue( AbstractAction.SHORT_DESCRIPTION, evt.getNewValue() );
264 			else if( evt.getPropertyName().equals( Inspector.ENABLED_PROPERTY ) )
265 			{
266 				boolean enable = ( ( Boolean )evt.getNewValue() ).booleanValue();
267 				setEnabled( enable );
268 
269 				if( !enable && currentInspector == inspector )
270 				{
271 					inspectorButtons.get( currentInspector ).setSelected( false );
272 				}
273 			}
274 		}
275 	}
276 
277 	public void release()
278 	{
279 		for( Inspector inspector : inspectors )
280 		{
281 			inspector.removePropertyChangeListener( this );
282 			inspector.release();
283 		}
284 
285 		inspectors.clear();
286 		inspectorPanel.removeAll();
287 		mainSplit.removeAll();
288 	}
289 
290 	public List<Inspector> getInspectors()
291 	{
292 		return inspectors;
293 	}
294 
295 	public Inspector getCurrentInspector()
296 	{
297 		return currentInspector;
298 	}
299 
300 	public void setInspectorsVisible( boolean b )
301 	{
302 		inspectorPanel.setVisible( b );
303 	}
304 
305 	public void setInspectorVisible( Inspector inspector, boolean b )
306 	{
307 		if( inspectorButtons.containsKey( inspector ) )
308 		{
309 			if( !b && inspector == currentInspector )
310 			{
311 				activate( null );
312 			}
313 
314 			inspectorButtons.get( inspector ).setVisible( b );
315 		}
316 	}
317 
318 	public void setToolbarVisible( boolean b )
319 	{
320 		inspectToolbar.setVisible( b );
321 	}
322 
323 	public double getResizeWeight()
324 	{
325 		return mainSplit.getResizeWeight();
326 	}
327 
328 	public void setResizeWeight( double value )
329 	{
330 		mainSplit.setResizeWeight( value );
331 	}
332 
333 	public int getDividerLocation()
334 	{
335 		return mainSplit.getDividerLocation();
336 	}
337 
338 	public void setResetDividerLocation()
339 	{
340 		mainSplit.setDividerLocation( defaultDividerLocation );
341 	}
342 
343 	public void setDividerLocation( int dividerLocation )
344 	{
345 		mainSplit.setDividerLocation( dividerLocation );
346 	}
347 
348 	public void setCurrentInspector( String string )
349 	{
350 		for( Inspector inspector : inspectors )
351 		{
352 			if( inspector.getTitle().equals( string ) )
353 			{
354 				activate( inspector );
355 				break;
356 			}
357 		}
358 	}
359 
360 	public void deactivate()
361 	{
362 		activate( null );
363 	}
364 
365 	public void activate( Inspector inspector )
366 	{
367 		if( inspector == currentInspector )
368 			return;
369 
370 		if( currentInspector != null )
371 		{
372 			inspectorButtons.get( currentInspector ).setSelected( false );
373 			currentInspector.deactivate();
374 		}
375 
376 		if( inspector == null )
377 		{
378 			currentInspector = null;
379 			inspectorPanel.setVisible( false );
380 		}
381 		else
382 		{
383 			JToggleButton button = inspectorButtons.get( inspector );
384 			currentInspector = inspector;
385 
386 			button.setSelected( true );
387 			button.setBackground( Color.WHITE );
388 
389 			if( !inspectorPanel.isVisible() )
390 			{
391 				inspectorPanel.setVisible( true );
392 				if( lastDividerLocation == 0 )
393 					mainSplit.setDividerLocation( defaultDividerLocation );
394 				else
395 					mainSplit.setDividerLocation( lastDividerLocation );
396 			}
397 
398 			CardLayout cards = ( CardLayout )inspectorPanel.getLayout();
399 			cards.show( inspectorPanel, inspector.getInspectorId() );
400 
401 			currentInspector.activate();
402 		}
403 	}
404 
405 	public void setContentComponent( JComponent content )
406 	{
407 		mainSplit.setTopComponent( content );
408 	}
409 
410 	public void removeInspector( Inspector inspector )
411 	{
412 		if( currentInspector == inspector )
413 		{
414 			deactivate();
415 		}
416 
417 		inspector.release();
418 		inspectors.remove( inspector );
419 		JToggleButton toggleButton = inspectorButtons.get( inspector );
420 
421 		int ix = inspectToolbar.getComponentIndex( toggleButton );
422 		if( ix > 1 )
423 			inspectToolbar.remove( ix - 1 );
424 
425 		inspectToolbar.remove( toggleButton );
426 		inspectorPanel.remove( inspector.getComponent() );
427 		inspectToolbar.repaint();
428 		inspectorButtons.remove( inspector );
429 	}
430 }