View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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.event.KeyAdapter;
24  import java.awt.event.KeyEvent;
25  import java.awt.event.MouseAdapter;
26  import java.awt.event.MouseEvent;
27  import java.beans.PropertyChangeEvent;
28  import java.beans.PropertyChangeListener;
29  import java.util.Arrays;
30  import java.util.HashMap;
31  import java.util.Map;
32  
33  import javax.swing.BorderFactory;
34  import javax.swing.Box;
35  import javax.swing.BoxLayout;
36  import javax.swing.JLabel;
37  import javax.swing.JPanel;
38  import javax.swing.JProgressBar;
39  
40  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
41  import com.eviware.soapui.impl.wsdl.actions.testsuite.AddNewTestCaseAction;
42  import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarTestCaseAdapter;
43  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
44  import com.eviware.soapui.model.ModelItem;
45  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
46  import com.eviware.soapui.model.testsuite.TestCase;
47  import com.eviware.soapui.support.UISupport;
48  import com.eviware.soapui.support.action.swing.ActionList;
49  import com.eviware.soapui.support.action.swing.ActionListBuilder;
50  import com.eviware.soapui.support.action.swing.ActionSupport;
51  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
52  import com.eviware.soapui.support.swing.AutoscrollSupport;
53  
54  /***
55   * A panel showing a scrollable list of TestCases in a TestSuite.
56   * 
57   * @author Ole.Matzura
58   */
59  
60  public class JTestCaseList extends JPanel 
61  {
62  	private Map<TestCase,TestCaseListPanel> panels = new HashMap<TestCase,TestCaseListPanel>();
63  	private final WsdlTestSuite testSuite;
64  	private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
65  
66  	public JTestCaseList(WsdlTestSuite testSuite)
67  	{
68  		this.testSuite = testSuite;
69  		setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ));
70  		
71  		for( int c = 0; c < testSuite.getTestCaseCount(); c++ )
72  		{
73  			TestCaseListPanel testCaseListPanel = createTestCaseListPanel( testSuite.getTestCaseAt( c ) );
74  			panels.put( testSuite.getTestCaseAt( c ), testCaseListPanel );
75  			add( testCaseListPanel );
76  		}
77  		
78  		add( Box.createVerticalGlue() );
79  		setBackground( Color.WHITE );
80  		
81  		testSuite.addTestSuiteListener( testSuiteListener );
82  		
83  		ActionList actions = ActionListBuilder.buildActions( testSuite );
84  		actions.removeAction( 0 );
85  		actions.removeAction( 0 );
86  		setComponentPopupMenu( ActionSupport.buildPopup( actions ));
87  	}
88  	
89  	@Override
90  	public void addNotify()
91  	{
92  		super.addNotify();
93  		testSuite.addTestSuiteListener( testSuiteListener );
94  		
95  	}
96  
97  	@Override
98  	public void removeNotify()
99  	{
100 		super.removeNotify();
101 		testSuite.removeTestSuiteListener( testSuiteListener );
102 	}
103 
104 	private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
105 	{
106 		public void testCaseAdded(TestCase testCase)
107 		{
108 			TestCaseListPanel testCaseListPanel = createTestCaseListPanel( testCase );
109 			panels.put( testCase, testCaseListPanel );
110 			add( testCaseListPanel, testCase.getTestSuite().getIndexOfTestCase( testCase ) );
111 			revalidate();
112 			repaint();
113 		}
114 
115 		public void testCaseRemoved(TestCase testCase)
116 		{
117 			TestCaseListPanel testCaseListPanel = panels.get( testCase );
118 			if( testCaseListPanel != null )
119 			{
120 				remove( testCaseListPanel );
121 				panels.remove( testCase );
122 				revalidate();
123 				repaint();
124 			}
125 		}
126 
127 		@Override
128 		public void testCaseMoved( TestCase testCase, int index, int offset )
129 		{
130 			TestCaseListPanel testCaseListPanel = panels.get( testCase );
131 			if( testCaseListPanel != null )
132 			{
133 				boolean hadFocus = testCaseListPanel.hasFocus();
134 				
135 				remove( testCaseListPanel );
136 				add( testCaseListPanel, index+offset );
137 				
138 				revalidate();
139 				repaint();
140 				
141 				if( hadFocus )
142 					testCaseListPanel.requestFocus();
143 			}
144 		}
145 	}
146 	
147 	public final class TestCaseListPanel extends JPanel implements Autoscroll
148 	{
149 		private final WsdlTestCase testCase;
150 		private JProgressBar progressBar;
151 		private JLabel label;
152 		private ProgressBarTestCaseAdapter progressBarAdapter;
153 		private boolean selected;
154 		private TestCasePropertyChangeListener testCasePropertyChangeListener;
155 		private AutoscrollSupport autoscrollSupport;
156 
157 		public TestCaseListPanel( WsdlTestCase testCase )
158 		{
159 			super( new BorderLayout() );
160 			
161 			setFocusable( true );
162 			
163 			this.testCase = testCase;
164 			autoscrollSupport = new AutoscrollSupport( this );
165 			
166 			progressBar = new JProgressBar( 0, 100 )
167 			{
168 				protected void processMouseEvent(MouseEvent e) {
169 			      if (e.getID() == MouseEvent.MOUSE_PRESSED ||
170 			        e.getID() == MouseEvent.MOUSE_RELEASED) {
171 			      	TestCaseListPanel.this.processMouseEvent(translateMouseEvent(e));
172 			      }
173 			    }
174 			    
175 			    protected void processMouseMotionEvent(MouseEvent e) {
176 			   	 TestCaseListPanel.this.processMouseMotionEvent(translateMouseEvent(e));
177 			    }
178 			    
179 			    /***
180 			     * Translates the given mouse event to the enclosing map panel's
181 			     * coordinate space.
182 			     */
183 			    private MouseEvent translateMouseEvent(MouseEvent e) {
184 			      return new MouseEvent(TestCaseListPanel.this, e.getID(), e.getWhen(), 
185 			        e.getModifiers(), e.getX() + getX(), e.getY() + getY(), 
186 			        e.getClickCount(), e.isPopupTrigger(), e.getButton());
187 			    }
188 			};
189 			
190 			JPanel progressPanel = UISupport.createProgressBarPanel( progressBar, 5, false );
191 			
192 		   progressBar.setMinimumSize( new Dimension( 0, 10 ));
193 		   progressBar.setBackground( Color.WHITE );
194 		   progressBar.setInheritsPopupMenu( true );
195 		   
196 			label = new JLabel( "TestCase: " + testCase.getName() );
197 			label.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5));
198 		   label.setInheritsPopupMenu( true );
199 
200 			add( progressPanel, BorderLayout.CENTER );
201 			add( label, BorderLayout.NORTH );
202 			
203 			testCasePropertyChangeListener = new TestCasePropertyChangeListener();
204 			
205 			ActionList actions = ActionListBuilder.buildActions( testCase );
206 			actions.insertAction( SwingActionDelegate.createDelegate( AddNewTestCaseAction.SOAPUI_ACTION_ID, testSuite, null, 
207 						null ), 0 );
208 			actions.insertAction( ActionSupport.SEPARATOR_ACTION, 1 );
209 			
210 			setComponentPopupMenu( ActionSupport.buildPopup( actions ));
211 			
212 			addMouseListener( new MouseAdapter() {
213 				
214 				@Override
215 				public void mousePressed( MouseEvent e )
216 				{
217 					requestFocus();
218 				}
219 
220 				public void mouseClicked(MouseEvent e)
221 				{
222 					if (e.getClickCount() < 2)
223 					{
224 						setSelected( !selected );
225 						return;
226 					}
227 					
228 					UISupport.selectAndShow( TestCaseListPanel.this.testCase );
229 				}
230 			} );
231 			
232 			addKeyListener( new TestCaseListPanelKeyHandler() );
233 			
234 			setSelected( false );
235 		}
236 		
237 		public void addNotify()
238 		{
239 			super.addNotify();
240 			testCase.addPropertyChangeListener( TestCase.NAME_PROPERTY, testCasePropertyChangeListener );
241 			progressBarAdapter = new ProgressBarTestCaseAdapter( progressBar, testCase );
242 		}
243 
244 		public void removeNotify()
245 		{
246 			super.removeNotify();
247 			if( progressBarAdapter != null )
248 			{
249 				testCase.removePropertyChangeListener( TestCase.NAME_PROPERTY, testCasePropertyChangeListener );
250 				progressBarAdapter.release();
251 				
252 				progressBarAdapter = null;
253 			}
254 		}
255 
256 		public Dimension getMaximumSize() 
257 		{
258 		    Dimension size = super.getMaximumSize();
259 		    size.height = 50;
260 		    return size;
261 		}
262 		
263 		public void setSelected( boolean selected )
264 		{
265 			this.selected = selected;
266 			
267 			if( selected )
268 			{
269 				setBackground( Color.YELLOW.brighter().brighter() );
270 				setBorder( BorderFactory.createLineBorder( Color.GRAY ));
271 			}
272 			else
273 			{
274 				setBackground( Color.WHITE );
275 				setBorder( BorderFactory.createLineBorder( Color.WHITE ));
276 			}
277 		}
278 
279 		public boolean isSelected()
280 		{
281 			return selected;
282 		}
283 		
284 		private final class TestCasePropertyChangeListener implements PropertyChangeListener
285 		{
286 			public void propertyChange(PropertyChangeEvent evt)
287 			{
288 				label.setText( "TestCase: " + TestCaseListPanel.this.testCase.getName() );
289 			}
290 		}
291 
292 		protected TestCase getTestCase()
293 		{
294 			return testCase;
295 		}
296 
297 		public ModelItem getModelItem()
298 		{
299 			return testCase;
300 		}
301 
302 		public void autoscroll( Point pt )
303 		{
304 			int ix = getIndexOf( this );
305 			if( pt.getY() < 12 && ix > 0 ) 
306 			{
307 				Rectangle bounds = JTestCaseList.this.getComponent( ix-1 ).getBounds();
308 				JTestCaseList.this.scrollRectToVisible( bounds );
309 			}
310 			else if( pt.getY() > getHeight()-12 && ix < testSuite.getTestCaseCount()-1 )
311 			{
312 				Rectangle bounds = JTestCaseList.this.getComponent( ix+1 ).getBounds();
313 				JTestCaseList.this.scrollRectToVisible( bounds );
314 			}
315 		}
316 
317 		public Insets getAutoscrollInsets()
318 		{
319 			return autoscrollSupport.getAutoscrollInsets();
320 		}
321 		
322 		private final class TestCaseListPanelKeyHandler extends KeyAdapter
323 		{
324 			public void keyPressed(KeyEvent e)
325 			{
326 				if (e.getKeyChar() == KeyEvent.VK_ENTER)
327 				{
328 					UISupport.selectAndShow( testCase );
329 					e.consume();
330 				}
331 				else
332 				{
333 					ActionList actions = ActionListBuilder.buildActions( testCase );
334 					if( actions != null )
335 						actions.dispatchKeyEvent( e );
336 				}
337 			}
338 		}
339 	}
340 	
341 	public int[] getSelectedIndices()
342 	{
343 		int cnt = 0;
344 		for( TestCaseListPanel panel : panels.values() )
345 		{
346 			if( panel.isSelected() ) cnt++;
347 		}
348 			
349 		int [] result = new int[cnt];
350 		cnt = 0;
351 		
352 		for( int c = 0; c < getComponentCount(); c++ )
353 		{
354 			Component comp = getComponent( c );
355 			if( comp instanceof TestCaseListPanel && ((TestCaseListPanel)comp).isSelected() )
356 			{
357 				result[cnt] = c;
358 				cnt++;
359 			}
360 		}
361 		
362 		return result;
363 	}
364 
365 	public int getIndexOf( TestCaseListPanel panel )
366 	{
367 		return Arrays.asList( getComponents() ).indexOf( panel );
368 	}
369 
370 	protected TestCaseListPanel createTestCaseListPanel( TestCase testCase )
371 	{
372 		TestCaseListPanel testCaseListPanel = new TestCaseListPanel(( WsdlTestCase ) testCase);
373 		return testCaseListPanel;
374 	}
375 }