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
229
230
231
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 }