View Javadoc

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