| package junit.swingui; |
| |
| import junit.framework.*; |
| import junit.runner.*; |
| |
| import java.util.*; |
| import java.lang.reflect.*; |
| import java.text.NumberFormat; |
| import java.net.URL; |
| import java.io.*; |
| |
| import javax.swing.*; |
| import javax.swing.event.*; |
| import javax.swing.text.*; |
| import java.awt.*; |
| import java.awt.event.*; |
| import java.awt.image.*; |
| |
| /** |
| * A Swing based user interface to run tests. |
| * Enter the name of a class which either provides a static |
| * suite method or is a subclass of TestCase. |
| * <pre> |
| * Synopsis: java junit.swingui.TestRunner [-noloading] [TestCase] |
| * </pre> |
| * TestRunner takes as an optional argument the name of the testcase class to be run. |
| */ |
| public class TestRunner extends BaseTestRunner implements TestRunContext { |
| protected JFrame fFrame; |
| private Thread fRunner; |
| private TestResult fTestResult; |
| |
| private JComboBox fSuiteCombo; |
| private ProgressBar fProgressIndicator; |
| private DefaultListModel fFailures; |
| private JLabel fLogo; |
| private CounterPanel fCounterPanel; |
| private JButton fRun; |
| private JButton fQuitButton; |
| private JButton fRerunButton; |
| private StatusLine fStatusLine; |
| private FailureDetailView fFailureView; |
| private JTabbedPane fTestViewTab; |
| private JCheckBox fUseLoadingRunner; |
| private Vector fTestRunViews= new Vector(); // view associated with tab in tabbed pane |
| private static Font PLAIN_FONT= StatusLine.PLAIN_FONT; |
| private static Font BOLD_FONT= StatusLine.BOLD_FONT; |
| private static final int GAP= 4; |
| private static final int HISTORY_LENGTH= 5; |
| |
| private static final String TESTCOLLECTOR_KEY= "TestCollectorClass"; |
| private static final String FAILUREDETAILVIEW_KEY= "FailureViewClass"; |
| |
| public TestRunner() { |
| } |
| |
| public static void main(String[] args) { |
| new TestRunner().start(args); |
| } |
| |
| public static void run(Class test) { |
| String args[]= { test.getName() }; |
| main(args); |
| } |
| |
| public void addError(final Test test, final Throwable t) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| fCounterPanel.setErrorValue(fTestResult.errorCount()); |
| appendFailure("Error", test, t); |
| } |
| } |
| ); |
| } |
| |
| public void addFailure(final Test test, final AssertionFailedError t) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| fCounterPanel.setFailureValue(fTestResult.failureCount()); |
| appendFailure("Failure", test, t); |
| } |
| } |
| ); |
| } |
| |
| public void startTest(Test test) { |
| postInfo("Running: "+test); |
| } |
| |
| public void endTest(Test test) { |
| postEndTest(test); |
| } |
| |
| private void postEndTest(final Test test) { |
| synchUI(); |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| if (fTestResult != null) { |
| fCounterPanel.setRunValue(fTestResult.runCount()); |
| fProgressIndicator.step(fTestResult.wasSuccessful()); |
| } |
| } |
| } |
| ); |
| } |
| |
| public void setSuite(String suiteName) { |
| fSuiteCombo.getEditor().setItem(suiteName); |
| } |
| |
| private void addToHistory(final String suite) { |
| for (int i= 0; i < fSuiteCombo.getItemCount(); i++) { |
| if (suite.equals(fSuiteCombo.getItemAt(i))) { |
| fSuiteCombo.removeItemAt(i); |
| fSuiteCombo.insertItemAt(suite, 0); |
| fSuiteCombo.setSelectedIndex(0); |
| return; |
| } |
| } |
| fSuiteCombo.insertItemAt(suite, 0); |
| fSuiteCombo.setSelectedIndex(0); |
| pruneHistory(); |
| } |
| |
| private void pruneHistory() { |
| int historyLength= getPreference("maxhistory", HISTORY_LENGTH); |
| if (historyLength < 1) |
| historyLength= 1; |
| for (int i= fSuiteCombo.getItemCount()-1; i > historyLength-1; i--) |
| fSuiteCombo.removeItemAt(i); |
| } |
| |
| private void appendFailure(String kind, Test test, Throwable t) { |
| fFailures.addElement(new TestFailure(test, t)); |
| if (fFailures.size() == 1) |
| revealFailure(test); |
| } |
| |
| private void revealFailure(Test test) { |
| for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) { |
| TestRunView v= (TestRunView) e.nextElement(); |
| v.revealFailure(test); |
| } |
| } |
| |
| protected void aboutToStart(final Test testSuite) { |
| for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) { |
| TestRunView v= (TestRunView) e.nextElement(); |
| v.aboutToStart(testSuite, fTestResult); |
| } |
| } |
| |
| protected void runFinished(final Test testSuite) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) { |
| TestRunView v= (TestRunView) e.nextElement(); |
| v.runFinished(testSuite, fTestResult); |
| } |
| } |
| } |
| ); |
| } |
| |
| protected CounterPanel createCounterPanel() { |
| return new CounterPanel(); |
| } |
| |
| protected JPanel createFailedPanel() { |
| JPanel failedPanel= new JPanel(new GridLayout(0, 1, 0, 2)); |
| fRerunButton= new JButton("Run"); |
| fRerunButton.setEnabled(false); |
| fRerunButton.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| rerun(); |
| } |
| } |
| ); |
| failedPanel.add(fRerunButton); |
| return failedPanel; |
| } |
| |
| protected FailureDetailView createFailureDetailView() { |
| String className= BaseTestRunner.getPreference(FAILUREDETAILVIEW_KEY); |
| if (className != null) { |
| Class viewClass= null; |
| try { |
| viewClass= Class.forName(className); |
| return (FailureDetailView)viewClass.newInstance(); |
| } catch(Exception e) { |
| JOptionPane.showMessageDialog(fFrame, "Could not create Failure DetailView - using default view"); |
| } |
| } |
| return new DefaultFailureDetailView(); |
| } |
| |
| /** |
| * Creates the JUnit menu. Clients override this |
| * method to add additional menu items. |
| */ |
| protected JMenu createJUnitMenu() { |
| JMenu menu= new JMenu("JUnit"); |
| menu.setMnemonic('J'); |
| JMenuItem mi1= new JMenuItem("About..."); |
| mi1.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| about(); |
| } |
| } |
| ); |
| mi1.setMnemonic('A'); |
| menu.add(mi1); |
| |
| menu.addSeparator(); |
| JMenuItem mi2= new JMenuItem(" Exit "); |
| mi2.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| terminate(); |
| } |
| } |
| ); |
| mi2.setMnemonic('x'); |
| menu.add(mi2); |
| |
| return menu; |
| } |
| |
| protected JFrame createFrame(String title) { |
| JFrame frame= new JFrame("JUnit"); |
| Image icon= loadFrameIcon(); |
| if (icon != null) |
| frame.setIconImage(icon); |
| frame.getContentPane().setLayout(new BorderLayout(0, 0)); |
| |
| frame.addWindowListener( |
| new WindowAdapter() { |
| public void windowClosing(WindowEvent e) { |
| terminate(); |
| } |
| } |
| ); |
| return frame; |
| } |
| |
| protected JLabel createLogo() { |
| JLabel label; |
| Icon icon= getIconResource(BaseTestRunner.class, "logo.gif"); |
| if (icon != null) |
| label= new JLabel(icon); |
| else |
| label= new JLabel("JV"); |
| label.setToolTipText("JUnit Version "+Version.id()); |
| return label; |
| } |
| |
| protected void createMenus(JMenuBar mb) { |
| mb.add(createJUnitMenu()); |
| } |
| |
| protected JCheckBox createUseLoaderCheckBox() { |
| boolean useLoader= useReloadingTestSuiteLoader(); |
| JCheckBox box= new JCheckBox("Reload classes every run", useLoader); |
| box.setToolTipText("Use a custom class loader to reload the classes for every run"); |
| if (inVAJava()) |
| box.setVisible(false); |
| return box; |
| } |
| |
| protected JButton createQuitButton() { |
| // spaces required to avoid layout flicker |
| // Exit is shorter than Stop that shows in the same column |
| JButton quit= new JButton(" Exit "); |
| quit.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| terminate(); |
| } |
| } |
| ); |
| return quit; |
| } |
| |
| protected JButton createRunButton() { |
| JButton run= new JButton("Run"); |
| run.setEnabled(true); |
| run.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| runSuite(); |
| } |
| } |
| ); |
| return run; |
| } |
| |
| protected Component createBrowseButton() { |
| JButton browse= new JButton("..."); |
| browse.setToolTipText("Select a Test class"); |
| browse.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| browseTestClasses(); |
| } |
| } |
| ); |
| return browse; |
| } |
| |
| protected StatusLine createStatusLine() { |
| return new StatusLine(420); |
| } |
| |
| protected JComboBox createSuiteCombo() { |
| JComboBox combo= new JComboBox(); |
| combo.setEditable(true); |
| combo.setLightWeightPopupEnabled(false); |
| |
| combo.getEditor().getEditorComponent().addKeyListener( |
| new KeyAdapter() { |
| public void keyTyped(KeyEvent e) { |
| textChanged(); |
| if (e.getKeyChar() == KeyEvent.VK_ENTER) |
| runSuite(); |
| } |
| } |
| ); |
| try { |
| loadHistory(combo); |
| } catch (IOException e) { |
| // fails the first time |
| } |
| combo.addItemListener( |
| new ItemListener() { |
| public void itemStateChanged(ItemEvent event) { |
| if (event.getStateChange() == ItemEvent.SELECTED) { |
| textChanged(); |
| } |
| } |
| } |
| ); |
| return combo; |
| } |
| |
| protected JTabbedPane createTestRunViews() { |
| JTabbedPane pane= new JTabbedPane(JTabbedPane.BOTTOM); |
| |
| FailureRunView lv= new FailureRunView(this); |
| fTestRunViews.addElement(lv); |
| lv.addTab(pane); |
| |
| TestHierarchyRunView tv= new TestHierarchyRunView(this); |
| fTestRunViews.addElement(tv); |
| tv.addTab(pane); |
| |
| pane.addChangeListener( |
| new ChangeListener() { |
| public void stateChanged(ChangeEvent e) { |
| testViewChanged(); |
| } |
| } |
| ); |
| return pane; |
| } |
| |
| public void testViewChanged() { |
| TestRunView view= (TestRunView)fTestRunViews.elementAt(fTestViewTab.getSelectedIndex()); |
| view.activate(); |
| } |
| |
| protected TestResult createTestResult() { |
| return new TestResult(); |
| } |
| |
| protected JFrame createUI(String suiteName) { |
| JFrame frame= createFrame("JUnit"); |
| JMenuBar mb= new JMenuBar(); |
| createMenus(mb); |
| frame.setJMenuBar(mb); |
| |
| JLabel suiteLabel= new JLabel("Test class name:"); |
| fSuiteCombo= createSuiteCombo(); |
| fRun= createRunButton(); |
| frame.getRootPane().setDefaultButton(fRun); |
| Component browseButton= createBrowseButton(); |
| |
| fUseLoadingRunner= createUseLoaderCheckBox(); |
| fProgressIndicator= new ProgressBar(); |
| fCounterPanel= createCounterPanel(); |
| |
| JLabel failureLabel= new JLabel("Errors and Failures:"); |
| fFailures= new DefaultListModel(); |
| |
| fTestViewTab= createTestRunViews(); |
| JPanel failedPanel= createFailedPanel(); |
| |
| fFailureView= createFailureDetailView(); |
| JScrollPane tracePane= new JScrollPane(fFailureView.getComponent(), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); |
| |
| fStatusLine= createStatusLine(); |
| fQuitButton= createQuitButton(); |
| fLogo= createLogo(); |
| |
| JPanel panel= new JPanel(new GridBagLayout()); |
| |
| addGrid(panel, suiteLabel, 0, 0, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, fSuiteCombo, 0, 1, 1, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, browseButton, 1, 1, 1, GridBagConstraints.NONE, 0.0, GridBagConstraints.WEST); |
| addGrid(panel, fRun, 2, 1, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.CENTER); |
| |
| addGrid(panel, fUseLoadingRunner, 0, 2, 3, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, new JSeparator(), 0, 3, 3, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| |
| |
| addGrid(panel, fProgressIndicator, 0, 4, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, fLogo, 2, 4, 1, GridBagConstraints.NONE, 0.0, GridBagConstraints.NORTH); |
| |
| addGrid(panel, fCounterPanel, 0, 5, 2, GridBagConstraints.NONE, 0.0, GridBagConstraints.CENTER); |
| |
| JSplitPane splitter= new JSplitPane(JSplitPane.VERTICAL_SPLIT, fTestViewTab, tracePane); |
| addGrid(panel, splitter, 0, 6, 2, GridBagConstraints.BOTH, 1.0, GridBagConstraints.WEST); |
| |
| addGrid(panel, failedPanel, 2, 6, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.NORTH/*CENTER*/); |
| |
| addGrid(panel, fStatusLine, 0, 8, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.CENTER); |
| addGrid(panel, fQuitButton, 2, 8, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.CENTER); |
| |
| frame.setContentPane(panel); |
| frame.pack(); |
| frame.setLocation(200, 200); |
| return frame; |
| } |
| |
| private void addGrid(JPanel p, Component co, int x, int y, int w, int fill, double wx, int anchor) { |
| GridBagConstraints c= new GridBagConstraints(); |
| c.gridx= x; c.gridy= y; |
| c.gridwidth= w; |
| c.anchor= anchor; |
| c.weightx= wx; |
| c.fill= fill; |
| if (fill == GridBagConstraints.BOTH || fill == GridBagConstraints.VERTICAL) |
| c.weighty= 1.0; |
| c.insets= new Insets(y == 0 ? GAP : 0, x == 0 ? GAP : 0, GAP, GAP); |
| p.add(co, c); |
| } |
| |
| protected String getSuiteText() { |
| if (fSuiteCombo == null) |
| return ""; |
| return (String)fSuiteCombo.getEditor().getItem(); |
| } |
| |
| public ListModel getFailures() { |
| return fFailures; |
| } |
| |
| public void insertUpdate(DocumentEvent event) { |
| textChanged(); |
| } |
| |
| public void browseTestClasses() { |
| TestCollector collector= createTestCollector(); |
| TestSelector selector= new TestSelector(fFrame, collector); |
| if (selector.isEmpty()) { |
| JOptionPane.showMessageDialog(fFrame, "No Test Cases found.\nCheck that the configured \'TestCollector\' is supported on this platform."); |
| return; |
| } |
| selector.show(); |
| String className= selector.getSelectedItem(); |
| if (className != null) |
| setSuite(className); |
| } |
| |
| TestCollector createTestCollector() { |
| String className= BaseTestRunner.getPreference(TESTCOLLECTOR_KEY); |
| if (className != null) { |
| Class collectorClass= null; |
| try { |
| collectorClass= Class.forName(className); |
| return (TestCollector)collectorClass.newInstance(); |
| } catch(Exception e) { |
| JOptionPane.showMessageDialog(fFrame, "Could not create TestCollector - using default collector"); |
| } |
| } |
| return new SimpleTestCollector(); |
| } |
| |
| private Image loadFrameIcon() { |
| ImageIcon icon= (ImageIcon)getIconResource(BaseTestRunner.class, "smalllogo.gif"); |
| if (icon != null) |
| return icon.getImage(); |
| return null; |
| } |
| |
| private void loadHistory(JComboBox combo) throws IOException { |
| BufferedReader br= new BufferedReader(new FileReader(getSettingsFile())); |
| int itemCount= 0; |
| try { |
| String line; |
| while ((line= br.readLine()) != null) { |
| combo.addItem(line); |
| itemCount++; |
| } |
| if (itemCount > 0) |
| combo.setSelectedIndex(0); |
| |
| } finally { |
| br.close(); |
| } |
| } |
| |
| private File getSettingsFile() { |
| String home= System.getProperty("user.home"); |
| return new File(home,".junitsession"); |
| } |
| |
| private void postInfo(final String message) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| showInfo(message); |
| } |
| } |
| ); |
| } |
| |
| private void postStatus(final String status) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| showStatus(status); |
| } |
| } |
| ); |
| } |
| |
| public void removeUpdate(DocumentEvent event) { |
| textChanged(); |
| } |
| |
| private void rerun() { |
| TestRunView view= (TestRunView)fTestRunViews.elementAt(fTestViewTab.getSelectedIndex()); |
| Test rerunTest= view.getSelectedTest(); |
| if (rerunTest != null) |
| rerunTest(rerunTest); |
| } |
| |
| private void rerunTest(Test test) { |
| if (!(test instanceof TestCase)) { |
| showInfo("Could not reload "+ test.toString()); |
| return; |
| } |
| Test reloadedTest= null; |
| try { |
| Class reloadedTestClass= getLoader().reload(test.getClass()); |
| Class[] classArgs= { String.class }; |
| Object[] args= new Object[]{((TestCase)test).getName()}; |
| Constructor constructor= reloadedTestClass.getConstructor(classArgs); |
| reloadedTest=(Test)constructor.newInstance(args); |
| } catch(Exception e) { |
| showInfo("Could not reload "+ test.toString()); |
| return; |
| } |
| TestResult result= new TestResult(); |
| reloadedTest.run(result); |
| |
| String message= reloadedTest.toString(); |
| if(result.wasSuccessful()) |
| showInfo(message+" was successful"); |
| else if (result.errorCount() == 1) |
| showStatus(message+" had an error"); |
| else |
| showStatus(message+" had a failure"); |
| } |
| |
| protected void reset() { |
| fCounterPanel.reset(); |
| fProgressIndicator.reset(); |
| fRerunButton.setEnabled(false); |
| fFailureView.clear(); |
| fFailures.clear(); |
| } |
| |
| /** |
| * runs a suite. |
| * @deprecated use runSuite() instead |
| */ |
| public void run() { |
| runSuite(); |
| } |
| |
| protected void runFailed(String message) { |
| showStatus(message); |
| fRun.setText("Run"); |
| fRunner= null; |
| } |
| |
| synchronized public void runSuite() { |
| if (fRunner != null) { |
| fTestResult.stop(); |
| } else { |
| setLoading(shouldReload()); |
| reset(); |
| showInfo("Load Test Case..."); |
| final String suiteName= getSuiteText(); |
| final Test testSuite= getTest(suiteName); |
| if (testSuite != null) { |
| addToHistory(suiteName); |
| doRunTest(testSuite); |
| } |
| } |
| } |
| |
| private boolean shouldReload() { |
| return !inVAJava() && fUseLoadingRunner.isSelected(); |
| } |
| |
| |
| synchronized protected void runTest(final Test testSuite) { |
| if (fRunner != null) { |
| fTestResult.stop(); |
| } else { |
| reset(); |
| if (testSuite != null) { |
| doRunTest(testSuite); |
| } |
| } |
| } |
| |
| private void doRunTest(final Test testSuite) { |
| setButtonLabel(fRun, "Stop"); |
| fRunner= new Thread("TestRunner-Thread") { |
| public void run() { |
| TestRunner.this.start(testSuite); |
| postInfo("Running..."); |
| |
| long startTime= System.currentTimeMillis(); |
| testSuite.run(fTestResult); |
| |
| if (fTestResult.shouldStop()) { |
| postStatus("Stopped"); |
| } else { |
| long endTime= System.currentTimeMillis(); |
| long runTime= endTime-startTime; |
| postInfo("Finished: " + elapsedTimeAsString(runTime) + " seconds"); |
| } |
| runFinished(testSuite); |
| setButtonLabel(fRun, "Run"); |
| fRunner= null; |
| System.gc(); |
| } |
| }; |
| // make sure that the test result is created before we start the |
| // test runner thread so that listeners can register for it. |
| fTestResult= createTestResult(); |
| fTestResult.addListener(TestRunner.this); |
| aboutToStart(testSuite); |
| |
| fRunner.start(); |
| } |
| |
| private void saveHistory() throws IOException { |
| BufferedWriter bw= new BufferedWriter(new FileWriter(getSettingsFile())); |
| try { |
| for (int i= 0; i < fSuiteCombo.getItemCount(); i++) { |
| String testsuite= fSuiteCombo.getItemAt(i).toString(); |
| bw.write(testsuite, 0, testsuite.length()); |
| bw.newLine(); |
| } |
| } finally { |
| bw.close(); |
| } |
| } |
| |
| private void setButtonLabel(final JButton button, final String label) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| button.setText(label); |
| } |
| } |
| ); |
| } |
| |
| private void setLabelValue(final JTextField label, final int value) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| label.setText(Integer.toString(value)); |
| } |
| } |
| ); |
| } |
| |
| public void handleTestSelected(Test test) { |
| fRerunButton.setEnabled(test != null && (test instanceof TestCase)); |
| showFailureDetail(test); |
| } |
| |
| private void showFailureDetail(Test test) { |
| if (test != null) { |
| ListModel failures= getFailures(); |
| for (int i= 0; i < failures.getSize(); i++) { |
| TestFailure failure= (TestFailure)failures.getElementAt(i); |
| if (failure.failedTest() == test) { |
| fFailureView.showFailure(failure); |
| return; |
| } |
| } |
| } |
| fFailureView.clear(); |
| } |
| |
| private void showInfo(String message) { |
| fStatusLine.showInfo(message); |
| } |
| |
| private void showStatus(String status) { |
| fStatusLine.showError(status); |
| } |
| |
| /** |
| * Starts the TestRunner |
| */ |
| public void start(String[] args) { |
| String suiteName= processArguments(args); |
| fFrame= createUI(suiteName); |
| fFrame.pack(); |
| fFrame.setVisible(true); |
| |
| if (suiteName != null) { |
| setSuite(suiteName); |
| runSuite(); |
| } |
| } |
| |
| private void start(final Test test) { |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| int total= test.countTestCases(); |
| fProgressIndicator.start(total); |
| fCounterPanel.setTotal(total); |
| } |
| } |
| ); |
| } |
| |
| /** |
| * Wait until all the events are processed in the event thread |
| */ |
| private void synchUI() { |
| try { |
| SwingUtilities.invokeAndWait( |
| new Runnable() { |
| public void run() {} |
| } |
| ); |
| } |
| catch (Exception e) { |
| } |
| } |
| |
| /** |
| * Terminates the TestRunner |
| */ |
| public void terminate() { |
| fFrame.dispose(); |
| try { |
| saveHistory(); |
| } catch (IOException e) { |
| System.out.println("Couldn't save test run history"); |
| } |
| System.exit(0); |
| } |
| |
| public void textChanged() { |
| fRun.setEnabled(getSuiteText().length() > 0); |
| clearStatus(); |
| } |
| |
| protected void clearStatus() { |
| fStatusLine.clear(); |
| } |
| |
| public static Icon getIconResource(Class clazz, String name) { |
| URL url= clazz.getResource(name); |
| if (url == null) { |
| System.err.println("Warning: could not load \""+name+"\" icon"); |
| return null; |
| } |
| return new ImageIcon(url); |
| } |
| |
| private void about() { |
| AboutDialog about= new AboutDialog(fFrame); |
| about.show(); |
| } |
| |
| |
| } |