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