1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.request.components.editor;
14
15 import java.awt.BorderLayout;
16 import java.awt.CardLayout;
17 import java.awt.Color;
18 import java.awt.event.ActionEvent;
19 import java.beans.PropertyChangeEvent;
20 import java.beans.PropertyChangeListener;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import javax.swing.AbstractAction;
27 import javax.swing.JComponent;
28 import javax.swing.JPanel;
29 import javax.swing.JSplitPane;
30 import javax.swing.JTabbedPane;
31 import javax.swing.JToggleButton;
32 import javax.swing.event.ChangeEvent;
33 import javax.swing.event.ChangeListener;
34
35 import com.eviware.soapui.support.UISupport;
36 import com.eviware.soapui.support.components.JXToolBar;
37 import com.eviware.soapui.support.components.VTextIcon;
38 import com.eviware.soapui.support.components.VerticalTabbedPaneUI;
39
40 @SuppressWarnings("serial")
41 public class XmlEditor extends JPanel implements PropertyChangeListener, XmlLocationListener
42 {
43 private static final float DEFAULT_DIVIDER_LOCATION = 0.7F;
44 private JTabbedPane inputTabs;
45 private List<XmlEditorView> views = new ArrayList<XmlEditorView>();
46 private XmlEditorView currentView;
47 private XmlDocument xmlDocument;
48 private List<XmlInspector> inspectors = new ArrayList<XmlInspector>();
49 protected JSplitPane mainSplit;
50 private JXToolBar inspectToolbar;
51 private Map<XmlInspector,JToggleButton> inspectorButtons = new HashMap<XmlInspector,JToggleButton>();
52 private XmlInspector currentInspector;
53 private JPanel inspectorPanel;
54 private int lastDividerLocation = 0;
55
56 public XmlEditor( XmlDocument xmlDocument )
57 {
58 super( new BorderLayout() );
59 this.xmlDocument = xmlDocument;
60
61 setBackground(Color.LIGHT_GRAY);
62 inputTabs = new JTabbedPane(JTabbedPane.LEFT, JTabbedPane.SCROLL_TAB_LAYOUT);
63 inputTabs.setUI(new VerticalTabbedPaneUI());
64
65 inputTabs.setFont(inputTabs.getFont().deriveFont(8));
66
67 inputTabs.addChangeListener( new ChangeListener()
68 {
69 public void stateChanged( ChangeEvent e )
70 {
71 int currentViewIndex = views.indexOf( currentView );
72
73 if( currentView != null )
74 {
75 if( inputTabs.getSelectedIndex() == currentViewIndex)
76 return;
77
78 if( !currentView.deactivate() )
79 {
80 inputTabs.setSelectedIndex( currentViewIndex );
81 return;
82 }
83 }
84
85 XmlEditorView previousView = currentView;
86 int selectedIndex = inputTabs.getSelectedIndex();
87 if( selectedIndex == -1 )
88 {
89 currentView = null;
90 return;
91 }
92
93 currentView = views.get( selectedIndex );
94
95 if( currentView != null && !currentView.activate( previousView == null ? null : previousView.getLocation() ))
96 {
97 inputTabs.setSelectedIndex( currentViewIndex );
98 if( currentViewIndex == -1 )
99 return;
100
101 currentView.getComponent().requestFocus();
102 }
103
104 if( !currentView.isInspectable() && currentInspector != null )
105 lastDividerLocation = mainSplit.getDividerLocation();
106
107 inspectorPanel.setVisible( currentView.isInspectable() && currentInspector != null );
108 inspectToolbar.setVisible( currentView.isInspectable() );
109
110 if( currentView.isInspectable() && currentInspector != null )
111 {
112 if( lastDividerLocation == 0 )
113 mainSplit.setDividerLocation( DEFAULT_DIVIDER_LOCATION );
114 else
115 mainSplit.setDividerLocation( lastDividerLocation );
116 }
117 }
118 } );
119
120 inspectorPanel = new JPanel(new CardLayout());
121 inspectorPanel.setVisible( false );
122
123 mainSplit = new JSplitPane( JSplitPane.VERTICAL_SPLIT, inputTabs, inspectorPanel );
124 mainSplit.setDividerSize( 10 );
125 mainSplit.setBorder( null );
126 mainSplit.setOneTouchExpandable( false );
127
128 add(mainSplit, BorderLayout.CENTER);
129 add( createInspectButtons(), BorderLayout.PAGE_END );
130
131 mainSplit.setResizeWeight( 0.8 );
132 }
133
134 private JComponent createInspectButtons()
135 {
136 inspectToolbar = UISupport.createToolbar();
137 inspectToolbar.addSpace( 10 );
138 inspectToolbar.setBackground( Color.WHITE );
139 inspectToolbar.setOpaque( true );
140 return inspectToolbar;
141 }
142
143 public void addInspector( XmlInspector inspector )
144 {
145 if( inspectors.size() > 0 )
146 {
147 inspectToolbar.addSeparator();
148 }
149
150 inspectors.add( inspector );
151 inspectorPanel.add( inspector.getComponent(), inspector.getClass().getName() );
152
153 JToggleButton button = new JToggleButton( new SelectInspectorAction( inspector ));
154
155 button.setToolTipText( inspector.getDescription() );
156 button.setOpaque( true );
157
158 inspectorButtons.put( inspector, button );
159 inspectToolbar.add( button );
160 inspectToolbar.addRelatedGap();
161 }
162
163 public void addEditorView( XmlEditorView editorView )
164 {
165 views.add( editorView );
166
167 inputTabs.addTab( null, new VTextIcon(inputTabs, editorView.getTitle(), VTextIcon.ROTATE_LEFT ),
168 editorView.getComponent() );
169
170 editorView.addPropertyChangeListener( XmlEditorView.TITLE_PROPERTY, this );
171 editorView.addLocationListener( this );
172
173 editorView.setXmlDocument( xmlDocument );
174 }
175
176 public void propertyChange(PropertyChangeEvent evt)
177 {
178 int ix = views.indexOf( evt.getSource() );
179 if( ix == -1 )
180 return;
181
182 inputTabs.setTitleAt( ix, (String) evt.getNewValue() );
183 }
184
185 public void selectView( int viewIndex )
186 {
187 inputTabs.setSelectedIndex( viewIndex );
188 }
189
190 public void requestFocus()
191 {
192 if( currentView != null )
193 currentView.getComponent().requestFocus();
194 }
195
196 public final XmlDocument getXmlDocument()
197 {
198 return xmlDocument;
199 }
200
201 public boolean hasFocus()
202 {
203 return currentView == null ? false : currentView.getComponent().hasFocus();
204 }
205
206 public final void setXmlDocument(XmlDocument xmlDocument)
207 {
208 this.xmlDocument = xmlDocument;
209
210 for( XmlEditorView view : views )
211 {
212 view.setXmlDocument( xmlDocument );
213 }
214 }
215
216 public final XmlEditorView getCurrentView()
217 {
218 return currentView;
219 }
220
221 public final JTabbedPane getInputTabs()
222 {
223 return inputTabs;
224 }
225
226 public final List<XmlEditorView> getViews()
227 {
228 return views;
229 }
230
231 public XmlEditorView getView( String viewId )
232 {
233 for( XmlEditorView view : views )
234 {
235 if( view.getViewId().equals( viewId ))
236 return view;
237 }
238
239 return null;
240 }
241
242 public XmlInspector getInspector( String inspectorId )
243 {
244 for( XmlInspector inspector : inspectors )
245 {
246 if( inspector.getInspectorId().equals( inspectorId ))
247 return inspector;
248 }
249
250 return null;
251 }
252
253 public void locationChanged(XmlLocation location)
254 {
255 if( location != null )
256 {
257 for( XmlInspector inspector : inspectors )
258 {
259 inspector.locationChanged( location );
260 }
261 }
262 }
263
264 public void setEditable( boolean enabled )
265 {
266 for( XmlEditorView view : views )
267 {
268 view.setEditable( enabled );
269 }
270 }
271
272 public class SelectInspectorAction extends AbstractAction implements PropertyChangeListener
273 {
274 private final XmlInspector inspector;
275
276 public SelectInspectorAction( XmlInspector inspector )
277 {
278 super( inspector.getTitle());
279 this.inspector = inspector;
280 inspector.addPropertyChangeListener( this );
281 }
282
283 public void actionPerformed( ActionEvent arg0 )
284 {
285 JToggleButton button = inspectorButtons.get( inspector );
286 if( !button.isSelected() )
287 {
288 currentInspector = null;
289 button.setBackground( inspectToolbar.getBackground() );
290 lastDividerLocation = mainSplit.getDividerLocation();
291 inspectorPanel.setVisible( false );
292 }
293 else
294 {
295 if( currentInspector != null )
296 inspectorButtons.get( currentInspector ).setSelected( false );
297
298 currentInspector = inspector;
299 button.setBackground( Color.WHITE );
300
301 if( !inspectorPanel.isVisible() )
302 {
303 inspectorPanel.setVisible( true );
304 if( lastDividerLocation == 0 )
305 mainSplit.setDividerLocation( DEFAULT_DIVIDER_LOCATION );
306 else
307 mainSplit.setDividerLocation( lastDividerLocation );
308 }
309
310 CardLayout cards = ( CardLayout ) inspectorPanel.getLayout();
311 cards.show( inspectorPanel, inspector.getClass().getName() );
312 }
313 }
314
315 public void propertyChange( PropertyChangeEvent evt )
316 {
317 if( evt.getPropertyName().equals( XmlInspector.TITLE_PROPERTY ))
318 putValue( AbstractAction.NAME, evt.getNewValue() );
319 else if( evt.getPropertyName().equals( XmlInspector.DESCRIPTION_PROPERTY ))
320 putValue( AbstractAction.SHORT_DESCRIPTION, evt.getNewValue() );
321 else if( evt.getPropertyName().equals( XmlInspector.ENABLED_PROPERTY ))
322 {
323 boolean enable = ((Boolean)evt.getNewValue()).booleanValue();
324 setEnabled( enable );
325
326 if( !enable && currentInspector == inspector )
327 {
328 inspectorButtons.get( currentInspector ).setSelected( false );
329 }
330 }
331 }
332 }
333 }