TestSelector.java revision 58a8b0aba2dec5695628a2bf25a3fae42c2c3533
1package junit.swingui;
2
3import java.awt.Component;
4import java.awt.Cursor;
5import java.awt.Dimension;
6import java.awt.Frame;
7import java.awt.GridBagConstraints;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.Toolkit;
11import java.awt.event.ActionEvent;
12import java.awt.event.ActionListener;
13import java.awt.event.KeyAdapter;
14import java.awt.event.KeyEvent;
15import java.awt.event.MouseAdapter;
16import java.awt.event.MouseEvent;
17import java.awt.event.WindowAdapter;
18import java.awt.event.WindowEvent;
19import java.util.Enumeration;
20import java.util.Vector;
21
22import javax.swing.DefaultListCellRenderer;
23import javax.swing.Icon;
24import javax.swing.JButton;
25import javax.swing.JDialog;
26import javax.swing.JLabel;
27import javax.swing.JList;
28import javax.swing.JScrollPane;
29import javax.swing.ListModel;
30import javax.swing.ListSelectionModel;
31import javax.swing.UIManager;
32import javax.swing.event.ListSelectionEvent;
33import javax.swing.event.ListSelectionListener;
34
35import junit.runner.Sorter;
36import junit.runner.TestCollector;
37
38/**
39 * A test class selector. A simple dialog to pick the name of a test suite.
40 */
41public class TestSelector extends JDialog {
42	private JButton fCancel;
43	private JButton fOk;
44	private JList fList;
45	private JScrollPane fScrolledList;
46	private JLabel fDescription;
47	private String fSelectedItem;
48
49	/**
50	 * Renders TestFailures in a JList
51	 */
52	static class TestCellRenderer extends DefaultListCellRenderer {
53		Icon fLeafIcon;
54		Icon fSuiteIcon;
55
56		public TestCellRenderer() {
57			fLeafIcon= UIManager.getIcon("Tree.leafIcon");
58			fSuiteIcon= UIManager.getIcon("Tree.closedIcon");
59		}
60
61		public Component getListCellRendererComponent(
62				JList list, Object value, int modelIndex,
63				boolean isSelected, boolean cellHasFocus) {
64			Component c= super.getListCellRendererComponent(list, value, modelIndex, isSelected, cellHasFocus);
65			String displayString= displayString((String)value);
66
67			if (displayString.startsWith("AllTests"))
68				setIcon(fSuiteIcon);
69			else
70				setIcon(fLeafIcon);
71
72			setText(displayString);
73		    	return c;
74		}
75
76		public static String displayString(String className) {
77			int typeIndex= className.lastIndexOf('.');
78    			if (typeIndex < 0)
79    				return className;
80    			return className.substring(typeIndex+1) + " - " + className.substring(0, typeIndex);
81		}
82
83		public static boolean matchesKey(String s, char ch) {
84    			return ch == Character.toUpperCase(s.charAt(typeIndex(s)));
85		}
86
87		private static int typeIndex(String s) {
88			int typeIndex= s.lastIndexOf('.');
89			int i= 0;
90    			if (typeIndex > 0)
91    				i= typeIndex+1;
92    			return i;
93		}
94	}
95
96	protected class DoubleClickListener extends MouseAdapter {
97		public void mouseClicked(MouseEvent e) {
98	    		if (e.getClickCount() == 2) {
99	    			okSelected();
100	    		}
101	      }
102	}
103
104	protected class KeySelectListener extends KeyAdapter {
105		public void keyTyped(KeyEvent e) {
106			keySelectTestClass(e.getKeyChar());
107		}
108	}
109
110	public TestSelector(Frame parent, TestCollector testCollector) {
111		super(parent, true);
112		setSize(350, 300);
113		setResizable(false);
114		// setLocationRelativeTo only exists in 1.4
115		try {
116			setLocationRelativeTo(parent);
117		} catch (NoSuchMethodError e) {
118			centerWindow(this);
119		}
120		setTitle("Test Selector");
121
122		Vector list= null;
123		try {
124			parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
125			list= createTestList(testCollector);
126		} finally {
127			parent.setCursor(Cursor.getDefaultCursor());
128		}
129		fList= new JList(list);
130		fList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
131		fList.setCellRenderer(new TestCellRenderer());
132		fScrolledList= new JScrollPane(fList);
133
134		fCancel= new JButton("Cancel");
135		fDescription= new JLabel("Select the Test class:");
136		fOk= new JButton("OK");
137		fOk.setEnabled(false);
138		getRootPane().setDefaultButton(fOk);
139
140		defineLayout();
141		addListeners();
142	}
143
144	public static void centerWindow(Component c) {
145		Dimension paneSize= c.getSize();
146		Dimension screenSize= c.getToolkit().getScreenSize();
147		c.setLocation((screenSize.width-paneSize.width)/2, (screenSize.height-paneSize.height)/2);
148	}
149
150	private void addListeners() {
151		fCancel.addActionListener(
152			new ActionListener() {
153				public void actionPerformed(ActionEvent e) {
154					dispose();
155				}
156			}
157		);
158
159		fOk.addActionListener(
160			new ActionListener() {
161				public void actionPerformed(ActionEvent e) {
162					okSelected();
163				}
164			}
165		);
166
167		fList.addMouseListener(new DoubleClickListener());
168		fList.addKeyListener(new KeySelectListener());
169		fList.addListSelectionListener(
170			new ListSelectionListener() {
171				public void valueChanged(ListSelectionEvent e) {
172					checkEnableOK(e);
173				}
174			}
175		);
176
177		addWindowListener(
178			new WindowAdapter() {
179				public void windowClosing(WindowEvent e) {
180					dispose();
181				}
182			}
183		);
184	}
185
186	private void defineLayout() {
187		getContentPane().setLayout(new GridBagLayout());
188		GridBagConstraints labelConstraints = new GridBagConstraints();
189		labelConstraints.gridx= 0; labelConstraints.gridy= 0;
190		labelConstraints.gridwidth= 1; labelConstraints.gridheight= 1;
191		labelConstraints.fill= GridBagConstraints.BOTH;
192		labelConstraints.anchor= GridBagConstraints.WEST;
193		labelConstraints.weightx= 1.0;
194		labelConstraints.weighty= 0.0;
195		labelConstraints.insets= new Insets(8, 8, 0, 8);
196		getContentPane().add(fDescription, labelConstraints);
197
198		GridBagConstraints listConstraints = new GridBagConstraints();
199		listConstraints.gridx= 0; listConstraints.gridy= 1;
200		listConstraints.gridwidth= 4; listConstraints.gridheight= 1;
201		listConstraints.fill= GridBagConstraints.BOTH;
202		listConstraints.anchor= GridBagConstraints.CENTER;
203		listConstraints.weightx= 1.0;
204		listConstraints.weighty= 1.0;
205		listConstraints.insets= new Insets(8, 8, 8, 8);
206		getContentPane().add(fScrolledList, listConstraints);
207
208		GridBagConstraints okConstraints= new GridBagConstraints();
209		okConstraints.gridx= 2; okConstraints.gridy= 2;
210		okConstraints.gridwidth= 1; okConstraints.gridheight= 1;
211		okConstraints.anchor= java.awt.GridBagConstraints.EAST;
212		okConstraints.insets= new Insets(0, 8, 8, 8);
213		getContentPane().add(fOk, okConstraints);
214
215
216		GridBagConstraints cancelConstraints = new GridBagConstraints();
217		cancelConstraints.gridx= 3; cancelConstraints.gridy= 2;
218		cancelConstraints.gridwidth= 1; cancelConstraints.gridheight= 1;
219		cancelConstraints.anchor= java.awt.GridBagConstraints.EAST;
220		cancelConstraints.insets= new Insets(0, 8, 8, 8);
221		getContentPane().add(fCancel, cancelConstraints);
222	}
223
224	public void checkEnableOK(ListSelectionEvent e) {
225		fOk.setEnabled(fList.getSelectedIndex() != -1);
226	}
227
228	public void okSelected() {
229		fSelectedItem= (String)fList.getSelectedValue();
230		dispose();
231	}
232
233	public boolean isEmpty() {
234		return fList.getModel().getSize() == 0;
235	}
236
237	public void keySelectTestClass(char ch) {
238		ListModel model= fList.getModel();
239		if (!Character.isJavaIdentifierStart(ch))
240			return;
241		for (int i= 0; i < model.getSize(); i++) {
242			String s= (String)model.getElementAt(i);
243			if (TestCellRenderer.matchesKey(s, Character.toUpperCase(ch))) {
244				fList.setSelectedIndex(i);
245				fList.ensureIndexIsVisible(i);
246				return;
247			}
248		}
249		Toolkit.getDefaultToolkit().beep();
250	}
251
252	public String getSelectedItem() {
253		return fSelectedItem;
254	}
255
256	private Vector createTestList(TestCollector collector) {
257    		Enumeration each= collector.collectTests();
258    		Vector v= new Vector(200);
259    		Vector displayVector= new Vector(v.size());
260    		while(each.hasMoreElements()) {
261    			String s= (String)each.nextElement();
262    			v.addElement(s);
263    			displayVector.addElement(TestCellRenderer.displayString(s));
264    		}
265    		if (v.size() > 0)
266    			Sorter.sortStrings(displayVector, 0, displayVector.size()-1, new ParallelSwapper(v));
267    		return v;
268	}
269
270	private class ParallelSwapper implements Sorter.Swapper {
271		Vector fOther;
272
273		ParallelSwapper(Vector other) {
274			fOther= other;
275		}
276		public void swap(Vector values, int left, int right) {
277			Object tmp= values.elementAt(left);
278			values.setElementAt(values.elementAt(right), left);
279			values.setElementAt(tmp, right);
280			Object tmp2= fOther.elementAt(left);
281			fOther.setElementAt(fOther.elementAt(right), left);
282			fOther.setElementAt(tmp2, right);
283		}
284	}
285}