1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.testsuite;
14
15 import java.awt.BorderLayout;
16 import java.awt.Color;
17 import java.awt.Component;
18 import java.awt.Dimension;
19 import java.awt.Insets;
20 import java.awt.Point;
21 import java.awt.Rectangle;
22 import java.awt.dnd.Autoscroll;
23 import java.awt.dnd.DnDConstants;
24 import java.awt.dnd.DragSource;
25 import java.awt.event.KeyAdapter;
26 import java.awt.event.KeyEvent;
27 import java.awt.event.MouseAdapter;
28 import java.awt.event.MouseEvent;
29 import java.beans.PropertyChangeEvent;
30 import java.beans.PropertyChangeListener;
31 import java.util.Arrays;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import javax.swing.BorderFactory;
36 import javax.swing.Box;
37 import javax.swing.BoxLayout;
38 import javax.swing.JComponent;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JProgressBar;
42
43 import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
44 import com.eviware.soapui.impl.wsdl.actions.testsuite.AddNewTestCaseAction;
45 import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarTestCaseAdapter;
46 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
47 import com.eviware.soapui.model.ModelItem;
48 import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
49 import com.eviware.soapui.model.testsuite.TestCase;
50 import com.eviware.soapui.support.UISupport;
51 import com.eviware.soapui.support.action.swing.ActionList;
52 import com.eviware.soapui.support.action.swing.ActionListBuilder;
53 import com.eviware.soapui.support.action.swing.ActionSupport;
54 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
55 import com.eviware.soapui.support.dnd.DropType;
56 import com.eviware.soapui.support.dnd.SoapUIDragAndDropHandler;
57 import com.eviware.soapui.support.dnd.SoapUIDragAndDropable;
58 import com.eviware.soapui.support.swing.AutoscrollSupport;
59
60 /***
61 * A panel showing a scrollable list of TestCases in a TestSuite.
62 *
63 * @author Ole.Matzura
64 */
65
66 public class JTestSuiteTestCaseList extends JPanel
67 {
68 private Map<TestCase, TestCaseListPanel> panels = new HashMap<TestCase, TestCaseListPanel>();
69 private final WsdlTestSuite testSuite;
70 private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
71 private TestCaseListPanel selectedTestCase;
72
73 public JTestSuiteTestCaseList( WsdlTestSuite testSuite )
74 {
75 this.testSuite = testSuite;
76 setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) );
77
78 for( int c = 0; c < testSuite.getTestCaseCount(); c++ )
79 {
80 TestCaseListPanel testCaseListPanel = createTestCaseListPanel( testSuite.getTestCaseAt( c ) );
81 panels.put( testSuite.getTestCaseAt( c ), testCaseListPanel );
82 add( testCaseListPanel );
83 }
84
85 add( Box.createVerticalGlue() );
86 setBackground( Color.WHITE );
87
88 testSuite.addTestSuiteListener( testSuiteListener );
89
90 ActionList actions = ActionListBuilder.buildActions( testSuite );
91 actions.removeAction( 0 );
92 actions.removeAction( 0 );
93 setComponentPopupMenu( ActionSupport.buildPopup( actions ) );
94
95 DragSource dragSource = DragSource.getDefaultDragSource();
96
97 SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler(
98 new TestCaseListDragAndDropable( this ), DropType.AFTER );
99
100 dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_COPY_OR_MOVE, dragAndDropHandler );
101 }
102
103 public void reset()
104 {
105 for( TestCaseListPanel testCasePanel : panels.values() )
106 {
107 testCasePanel.reset();
108 }
109 }
110
111 @Override
112 public void addNotify()
113 {
114 super.addNotify();
115 testSuite.addTestSuiteListener( testSuiteListener );
116 }
117
118 @Override
119 public void removeNotify()
120 {
121 super.removeNotify();
122 testSuite.removeTestSuiteListener( testSuiteListener );
123 }
124
125 private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
126 {
127 public void testCaseAdded( TestCase testCase )
128 {
129 TestCaseListPanel testCaseListPanel = createTestCaseListPanel( testCase );
130 panels.put( testCase, testCaseListPanel );
131 add( testCaseListPanel, testCase.getTestSuite().getIndexOfTestCase( testCase ) );
132 revalidate();
133 repaint();
134 }
135
136 public void testCaseRemoved( TestCase testCase )
137 {
138 TestCaseListPanel testCaseListPanel = panels.get( testCase );
139 if( testCaseListPanel != null )
140 {
141 remove( testCaseListPanel );
142 panels.remove( testCase );
143 revalidate();
144 repaint();
145 }
146 }
147
148 @Override
149 public void testCaseMoved( TestCase testCase, int index, int offset )
150 {
151 TestCaseListPanel testCaseListPanel = panels.get( testCase );
152 if( testCaseListPanel != null )
153 {
154 boolean hadFocus = testCaseListPanel.hasFocus();
155
156 remove( testCaseListPanel );
157 add( testCaseListPanel, index + offset );
158
159 revalidate();
160 repaint();
161
162 if( hadFocus )
163 testCaseListPanel.requestFocus();
164 }
165 }
166 }
167
168 public final class TestCaseListPanel extends JPanel implements Autoscroll
169 {
170 private final WsdlTestCase testCase;
171 private JProgressBar progressBar;
172 private JLabel label;
173 private ProgressBarTestCaseAdapter progressBarAdapter;
174 private TestCasePropertyChangeListener testCasePropertyChangeListener;
175 private AutoscrollSupport autoscrollSupport;
176
177 public TestCaseListPanel( WsdlTestCase testCase )
178 {
179 super( new BorderLayout() );
180
181 setFocusable( true );
182
183 this.testCase = testCase;
184 autoscrollSupport = new AutoscrollSupport( this );
185
186 progressBar = new JProgressBar( 0, 100 )
187 {
188 protected void processMouseEvent( MouseEvent e )
189 {
190 if( e.getID() == MouseEvent.MOUSE_PRESSED || e.getID() == MouseEvent.MOUSE_RELEASED )
191 {
192 TestCaseListPanel.this.processMouseEvent( translateMouseEvent( e ) );
193 }
194 }
195
196 protected void processMouseMotionEvent( MouseEvent e )
197 {
198 TestCaseListPanel.this.processMouseMotionEvent( translateMouseEvent( e ) );
199 }
200
201 /***
202 * Translates the given mouse event to the enclosing map panel's
203 * coordinate space.
204 */
205 private MouseEvent translateMouseEvent( MouseEvent e )
206 {
207 return new MouseEvent( TestCaseListPanel.this, e.getID(), e.getWhen(), e.getModifiers(), e.getX()
208 + getX(), e.getY() + getY(), e.getClickCount(), e.isPopupTrigger(), e.getButton() );
209 }
210 };
211
212 JPanel progressPanel = UISupport.createProgressBarPanel( progressBar, 5, false );
213
214 progressBar.setMinimumSize( new Dimension( 0, 10 ) );
215 progressBar.setBackground( Color.WHITE );
216 progressBar.setInheritsPopupMenu( true );
217
218 label = new JLabel( testCase.getLabel() );
219 label.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
220 label.setInheritsPopupMenu( true );
221 label.setEnabled( !testCase.isDisabled() );
222
223 add( progressPanel, BorderLayout.CENTER );
224 add( label, BorderLayout.NORTH );
225
226 testCasePropertyChangeListener = new TestCasePropertyChangeListener();
227
228 initPopup( testCase );
229
230 addMouseListener( new MouseAdapter()
231 {
232
233 @Override
234 public void mousePressed( MouseEvent e )
235 {
236 requestFocus();
237 }
238
239 public void mouseClicked( MouseEvent e )
240 {
241 if( e.getClickCount() < 2 )
242 {
243 if( selectedTestCase != null )
244 selectedTestCase.setSelected( false );
245
246 setSelected( true );
247 selectedTestCase = TestCaseListPanel.this;
248 return;
249 }
250
251 UISupport.selectAndShow( TestCaseListPanel.this.testCase );
252 }
253 } );
254
255 addKeyListener( new TestCaseListPanelKeyHandler() );
256
257
258 setSelected( false );
259 }
260
261 public void reset()
262 {
263 progressBar.setValue( 0 );
264 progressBar.setString( "" );
265 }
266
267 private void initPopup( WsdlTestCase testCase )
268 {
269 ActionList actions = ActionListBuilder.buildActions( testCase );
270 actions.insertAction( SwingActionDelegate.createDelegate( AddNewTestCaseAction.SOAPUI_ACTION_ID, testSuite,
271 null, null ), 0 );
272 actions.insertAction( ActionSupport.SEPARATOR_ACTION, 1 );
273
274 setComponentPopupMenu( ActionSupport.buildPopup( actions ) );
275 }
276
277 public void addNotify()
278 {
279 super.addNotify();
280 testCase.addPropertyChangeListener( testCasePropertyChangeListener );
281 progressBarAdapter = new ProgressBarTestCaseAdapter( progressBar, testCase );
282 }
283
284 public void removeNotify()
285 {
286 super.removeNotify();
287 if( progressBarAdapter != null )
288 {
289 testCase.removePropertyChangeListener( testCasePropertyChangeListener );
290 progressBarAdapter.release();
291
292 progressBarAdapter = null;
293 }
294 }
295
296 public Dimension getMaximumSize()
297 {
298 Dimension size = super.getMaximumSize();
299 size.height = 50;
300 return size;
301 }
302
303 public void setSelected( boolean selected )
304 {
305 if( selected )
306 {
307 setBorder( BorderFactory.createLineBorder( Color.GRAY ) );
308 }
309 else
310 {
311 setBorder( BorderFactory.createLineBorder( Color.WHITE ) );
312 }
313 }
314
315 public boolean isSelected()
316 {
317 return selectedTestCase != null && selectedTestCase.getTestCase() == testCase;
318 }
319
320 private final class TestCasePropertyChangeListener implements PropertyChangeListener
321 {
322 public void propertyChange( PropertyChangeEvent evt )
323 {
324 if( evt.getPropertyName().equals( TestCase.LABEL_PROPERTY ) )
325 {
326 label.setEnabled( !testCase.isDisabled() );
327 label.setText( testCase.getLabel() );
328 }
329 else if( evt.getPropertyName().equals( TestCase.DISABLED_PROPERTY ) )
330 {
331 initPopup( testCase );
332 }
333 }
334 }
335
336 protected TestCase getTestCase()
337 {
338 return testCase;
339 }
340
341 public ModelItem getModelItem()
342 {
343 return testCase;
344 }
345
346 public void autoscroll( Point pt )
347 {
348 int ix = getIndexOf( this );
349 if( pt.getY() < 12 && ix > 0 )
350 {
351 Rectangle bounds = JTestSuiteTestCaseList.this.getComponent( ix - 1 ).getBounds();
352 JTestSuiteTestCaseList.this.scrollRectToVisible( bounds );
353 }
354 else if( pt.getY() > getHeight() - 12 && ix < testSuite.getTestCaseCount() - 1 )
355 {
356 Rectangle bounds = JTestSuiteTestCaseList.this.getComponent( ix + 1 ).getBounds();
357 JTestSuiteTestCaseList.this.scrollRectToVisible( bounds );
358 }
359 }
360
361 public Insets getAutoscrollInsets()
362 {
363 return autoscrollSupport.getAutoscrollInsets();
364 }
365
366 private final class TestCaseListPanelKeyHandler extends KeyAdapter
367 {
368 public void keyPressed( KeyEvent e )
369 {
370 if( e.getKeyChar() == KeyEvent.VK_ENTER )
371 {
372 UISupport.selectAndShow( testCase );
373 e.consume();
374 }
375 else
376 {
377 ActionList actions = ActionListBuilder.buildActions( testCase );
378 if( actions != null )
379 actions.dispatchKeyEvent( e );
380 }
381 }
382 }
383 }
384
385 protected int getIndexOf( TestCaseListPanel panel )
386 {
387 return Arrays.asList( getComponents() ).indexOf( panel );
388 }
389
390 protected TestCaseListPanel createTestCaseListPanel( TestCase testCase )
391 {
392 TestCaseListPanel testCaseListPanel = new TestCaseListPanel( ( WsdlTestCase )testCase );
393
394 DragSource dragSource = DragSource.getDefaultDragSource();
395
396 SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler( new TestCaseListPanelDragAndDropable(
397 testCaseListPanel ), DropType.BEFORE_AND_AFTER );
398
399 dragSource.createDefaultDragGestureRecognizer( testCaseListPanel, DnDConstants.ACTION_COPY_OR_MOVE,
400 dragAndDropHandler );
401
402 return testCaseListPanel;
403 }
404
405 private class TestCaseListDragAndDropable implements SoapUIDragAndDropable<ModelItem>
406 {
407 private final JTestSuiteTestCaseList list;
408
409 public TestCaseListDragAndDropable( JTestSuiteTestCaseList list )
410 {
411 this.list = list;
412 }
413
414 public JComponent getComponent()
415 {
416 return list;
417 }
418
419 public Rectangle getModelItemBounds( ModelItem modelItem )
420 {
421 return list.getBounds();
422 }
423
424 public ModelItem getModelItemForLocation( int x, int y )
425 {
426 int testCaseCount = testSuite.getTestCaseCount();
427 return testCaseCount == 0 ? testSuite : testSuite.getTestCaseAt( testCaseCount - 1 );
428 }
429
430 public Component getRenderer( ModelItem modelItem )
431 {
432 return null;
433 }
434
435 public void selectModelItem( ModelItem modelItem )
436 {
437 }
438
439 public void setDragInfo( String dropInfo )
440 {
441 list.setToolTipText( dropInfo );
442 }
443
444 public void toggleExpansion( ModelItem modelItem )
445 {
446 }
447 }
448
449 private static class TestCaseListPanelDragAndDropable implements SoapUIDragAndDropable<ModelItem>
450 {
451 private final TestCaseListPanel testCasePanel;
452
453 public TestCaseListPanelDragAndDropable( TestCaseListPanel testCasePanel )
454 {
455 this.testCasePanel = testCasePanel;
456 }
457
458 public JComponent getComponent()
459 {
460 return testCasePanel;
461 }
462
463 public void setDragInfo( String dropInfo )
464 {
465 testCasePanel.setToolTipText( dropInfo.length() == 0 ? null : dropInfo );
466 }
467
468 public Rectangle getModelItemBounds( ModelItem path )
469 {
470 return new Rectangle( testCasePanel.getSize() );
471 }
472
473 public ModelItem getModelItemForLocation( int x, int y )
474 {
475 return testCasePanel.getModelItem();
476 }
477
478 public Component getRenderer( ModelItem path )
479 {
480 return null;
481 }
482
483 public void selectModelItem( ModelItem path )
484 {
485 testCasePanel.setSelected( !testCasePanel.isSelected() );
486 }
487
488 public void toggleExpansion( ModelItem last )
489 {
490 }
491 }
492 }