001: /******************************************************************************
002: * Copyright (C) Lars Ivar Almli. All rights reserved. *
003: * ---------------------------------------------------------------------------*
004: * This file is part of MActor. *
005: * *
006: * MActor is free software; you can redistribute it and/or modify *
007: * it under the terms of the GNU General Public License as published by *
008: * the Free Software Foundation; either version 2 of the License, or *
009: * (at your option) any later version. *
010: * *
011: * MActor is distributed in the hope that it will be useful, *
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
014: * GNU General Public License for more details. *
015: * *
016: * You should have received a copy of the GNU General Public License *
017: * along with MActor; if not, write to the Free Software *
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
019: ******************************************************************************/package org.mactor.ui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Color;
023: import java.awt.Cursor;
024: import java.awt.Dimension;
025: import java.awt.Frame;
026: import java.awt.GridLayout;
027: import java.awt.event.ActionEvent;
028: import java.awt.event.ActionListener;
029: import java.awt.event.KeyEvent;
030: import java.awt.event.MouseAdapter;
031: import java.awt.event.MouseEvent;
032: import java.io.File;
033: import java.io.IOException;
034: import java.net.URL;
035: import java.util.LinkedList;
036: import java.util.List;
037: import javax.swing.BorderFactory;
038: import javax.swing.JButton;
039: import javax.swing.JDialog;
040: import javax.swing.JEditorPane;
041: import javax.swing.JFileChooser;
042: import javax.swing.JFrame;
043: import javax.swing.JLabel;
044: import javax.swing.JMenu;
045: import javax.swing.JMenuBar;
046: import javax.swing.JMenuItem;
047: import javax.swing.JOptionPane;
048: import javax.swing.JPanel;
049: import javax.swing.JScrollPane;
050: import javax.swing.JTabbedPane;
051: import javax.swing.SwingUtilities;
052: import javax.swing.UIManager;
053: import javax.swing.filechooser.FileFilter;
054: import org.mactor.framework.HtmlTestSuiteParser;
055: import org.mactor.framework.spec.TestSpec;
056:
057: /**
058: * MActor GUI frontend
059: *
060: * @author Lars Ivar Almli
061: */
062: public class TestSuiteRunnerGui extends JFrame {
063: private static boolean useSystemLookAndFeel = false;
064: JFileChooser fc;
065: private boolean first = true;
066: private List<TestPanel> testPanels = new LinkedList<TestPanel>();
067: private File lastFile;
068: private JMenuItem reloadItem = new JMenuItem("Reload");
069: private AboutDlg aboutDlg;
070: private VersionDlg versionDlg;
071:
072: // private HelpDlg helpDlg;
073: public TestSuiteRunnerGui() throws IOException {
074: super ("MActor (" + VersionUtil.getVersion() + ")");
075: aboutDlg = new AboutDlg(this );
076: // helpDlg = new HelpDlg(this);
077: // setLayout(new BorderLayout());
078: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
079: fc = new JFileChooser(new File("."));
080: fc.setFileFilter(new SuiteFilter());
081: fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
082: JPanel contentPane = (JPanel) getContentPane();
083: contentPane.setLayout(new GridLayout(1, 1));
084: contentPane.setOpaque(true);
085: setJMenuBar(createMenuBar());
086: JEditorPane featuresPane = new JEditorPane(
087: "file:resources/frontpage.html");
088: featuresPane.addHyperlinkListener(BrowserUtil
089: .createLinkListener());
090: featuresPane.setEditable(false);
091: JScrollPane sp = new JScrollPane(featuresPane);
092: sp.setPreferredSize(new Dimension(580, 400));
093: contentPane.add(sp);// new JLabel(" Select the test data file ")
094: pack();
095: setVisible(true);
096: setResizable(false);
097: }
098:
099: public JMenuBar createMenuBar() {
100: JMenuBar menuBar = new JMenuBar();
101: // File
102: JMenu fileMenu = new JMenu("File");
103: fileMenu.setMnemonic(KeyEvent.VK_F);
104: JMenuItem openItem = new JMenuItem("Open...");
105: openItem.setMnemonic(KeyEvent.VK_O);
106: fileMenu.add(openItem);
107: JMenuItem exitItem = new JMenuItem("Exit");
108: exitItem.setMnemonic(KeyEvent.VK_E);
109: fileMenu.add(exitItem);
110: // fileMenu.addSeparator();
111: reloadItem.setMnemonic(KeyEvent.VK_R);
112: reloadItem.setVisible(false);
113: fileMenu.add(reloadItem);
114: menuBar.add(fileMenu);
115: JMenu helpMenu = new JMenu("Help");
116: helpMenu.setMnemonic(KeyEvent.VK_H);
117: JMenuItem helpItem = new JMenuItem("Help...");
118: helpItem.setMnemonic(KeyEvent.VK_H);
119: // helpMenu.add(helpItem);
120: JMenuItem versionItem = new JMenuItem("Check for new version");
121: versionItem.setMnemonic(KeyEvent.VK_C);
122: helpMenu.add(versionItem);
123: JMenuItem aboutItem = new JMenuItem("About...");
124: aboutItem.setMnemonic(KeyEvent.VK_A);
125: helpMenu.add(aboutItem);
126: menuBar.add(helpMenu);
127: // Help
128: helpItem.addActionListener(new ActionListener() {
129: public void actionPerformed(ActionEvent e) {
130: // helpDlg.setVisible(true);
131: }
132: });
133: aboutItem.addActionListener(new ActionListener() {
134: public void actionPerformed(ActionEvent e) {
135: aboutDlg.setVisible(true);
136: }
137: });
138: versionItem.addActionListener(new ActionListener() {
139: public void actionPerformed(ActionEvent e) {
140: if (versionDlg == null)
141: versionDlg = new VersionDlg(TestSuiteRunnerGui.this );
142: versionDlg.performCheck();
143: versionDlg.setVisible(true);
144: }
145: });
146: openItem.addActionListener(new ActionListener() {
147: public void actionPerformed(ActionEvent e) {
148: int returnVal = fc
149: .showOpenDialog(TestSuiteRunnerGui.this );
150: if (returnVal == JFileChooser.APPROVE_OPTION) {
151: lastFile = fc.getSelectedFile();
152: reloadItem.setText("Reload " + lastFile.getName());
153: reloadItem.setVisible(true);
154: addTestPanes(lastFile.getAbsolutePath());
155: }
156: }
157: });
158: exitItem.addActionListener(new ActionListener() {
159: public void actionPerformed(ActionEvent e) {
160: System.exit(0);
161: }
162: });
163: reloadItem.addActionListener(new ActionListener() {
164: public void actionPerformed(ActionEvent e) {
165: addTestPanes(lastFile.getAbsolutePath());
166: }
167: });
168: return menuBar;
169: }
170:
171: public class SuiteFilter extends FileFilter {
172: public boolean accept(File f) {
173: if (f.isDirectory()) {
174: return true;
175: }
176: return f.getName().toLowerCase().endsWith(".html");
177: }
178:
179: public String getDescription() {
180: return "HTML test data files";
181: }
182: }
183:
184: private void addTestPanes(String path) {
185: for (TestPanel t : testPanels) {
186: t.terminate();
187: }
188: testPanels.clear();
189: try {
190: List<HtmlTestSuiteParser> parsed = HtmlTestSuiteParser
191: .parseFile(path);
192: JTabbedPane tp = new JTabbedPane();
193: for (HtmlTestSuiteParser p : parsed) {
194: TestSpec ts = TestSpec.loadFromFile(new File(p
195: .getTestSpecPath()));
196: TestPanel testPanel = new TestPanel(ts, p.getData());
197: testPanels.add(testPanel);
198: tp.addTab(ts.getName(), testPanel);
199: }
200: JEditorPane htmlPane = new JEditorPane("file:" + path);
201: htmlPane.setEditable(false);
202: htmlPane.addHyperlinkListener(BrowserUtil
203: .createLinkListener());
204: JTabbedPane mainTabPane = new JTabbedPane();
205: mainTabPane.addTab("Tests", tp);
206: mainTabPane.addTab("HTML view", new JScrollPane(htmlPane));
207: getContentPane().removeAll();
208: getContentPane().setLayout(new GridLayout(1, 0));
209: getContentPane().add(mainTabPane);
210: setTitle("MActor (" + VersionUtil.getVersion() + ") - "
211: + new File(path).getName());
212: if (first) {
213: setResizable(true);
214: pack();
215: setExtendedState(Frame.MAXIMIZED_BOTH);
216: } else {
217: this .getRootPane().revalidate();
218: this .repaint();
219: }
220: first = false;
221: } catch (Exception me) {
222: me.printStackTrace();
223: JOptionPane.showMessageDialog(this , "Error:"
224: + me.getMessage(), "Failed to load the file",
225: JOptionPane.ERROR_MESSAGE);
226: this .getRootPane().revalidate();
227: this .repaint();
228: }
229: }
230:
231: /**
232: * Create the GUI and show it. For thread safety, this method should be
233: * invoked from the event-dispatching thread.
234: */
235: private static void createAndShowGUI() {
236: if (useSystemLookAndFeel) {
237: try {
238: UIManager.setLookAndFeel(UIManager
239: .getSystemLookAndFeelClassName());
240: } catch (Exception e) {
241: System.err
242: .println("Couldn't use system look and feel.");
243: }
244: }
245: try {
246: new TestSuiteRunnerGui();
247: } catch (Exception e) {
248: System.err.println("Failed to start GUI. Error:"
249: + e.getMessage());
250: System.exit(1);
251: }
252: }
253:
254: public static void main(String[] args) {
255: SwingUtilities.invokeLater(new Runnable() {
256: public void run() {
257: createAndShowGUI();
258: }
259: });
260:
261: }
262:
263: private class AboutDlg extends JDialog {
264: public AboutDlg(Frame parent) throws IOException {
265: super (parent);
266: setLayout(new BorderLayout());
267: setTitle("MActor - About");
268: JEditorPane aboutPane = new JEditorPane(
269: "file:resources/ABOUT");
270: aboutPane.setEditable(false);
271: aboutPane.addHyperlinkListener(BrowserUtil
272: .createLinkListener());
273: // aboutPane.setBackground(Color.LIGHT_GRAY);
274: JScrollPane sp = new JScrollPane(aboutPane);
275: sp.setPreferredSize(new Dimension(580, 400));
276: sp.setBorder(BorderFactory.createRaisedBevelBorder());
277: add(sp, BorderLayout.CENTER);
278: JButton b = new JButton("Ok");
279: JPanel bp = new JPanel();
280: bp.add(b);
281: add(bp, BorderLayout.SOUTH);
282: b.addActionListener(new ActionListener() {
283: public void actionPerformed(ActionEvent arg0) {
284: AboutDlg.this .setVisible(false);
285: }
286: });
287: pack();
288: setResizable(false);
289: }
290: }
291:
292: private class HelpDlg extends JDialog {
293: public HelpDlg(Frame parent) throws IOException {
294: super (parent);
295: setTitle("MActor - Help");
296: JEditorPane helpPane = new JEditorPane(
297: "file:doc/intro.html");
298: helpPane.setEditable(false);
299: helpPane.addHyperlinkListener(BrowserUtil
300: .createLinkListener());
301: JScrollPane sp = new JScrollPane(helpPane);
302: add(sp);
303: pack();
304: }
305: }
306:
307: private class VersionDlg extends JDialog {
308: JLabel status = new JLabel();
309: JLabel link = new JLabel("http://mactor.sourceforge.net");
310: JButton b = new JButton("Ok");
311:
312: public VersionDlg(Frame parent) {
313: super (parent);
314: setLayout(new BorderLayout());
315: setTitle("MActor - Check for new version");
316: link.setForeground(Color.blue);
317: status.setBorder(BorderFactory.createEmptyBorder(10, 10,
318: 10, 10));
319: link.setBorder(BorderFactory.createEmptyBorder(10, 0, 10,
320: 10));
321: add(status, BorderLayout.WEST);
322: add(link, BorderLayout.EAST);
323: //link.setFont(link.getFont().)
324:
325: JPanel bp = new JPanel();
326: bp.add(b);
327: add(bp, BorderLayout.SOUTH);
328: b.addActionListener(new ActionListener() {
329: public void actionPerformed(ActionEvent arg0) {
330: VersionDlg.this .setVisible(false);
331: }
332: });
333: link.addMouseListener(new MouseAdapter() {
334: @Override
335: public void mouseClicked(MouseEvent arg0) {
336: try {
337: BrowserUtil.openURL(new URL(link.getText()));
338: } catch (Exception e) {
339: e.printStackTrace();//ignore
340: }
341: }
342: });
343: //setPreferredSize(new Dimension(300,100));
344: pack();
345: setResizable(false);
346: }
347:
348: public void performCheck() {
349: link.setVisible(false);
350: status.setText("Checking for new version..");
351: b.setEnabled(false);
352: this .setCursor(Cursor
353: .getPredefinedCursor(Cursor.WAIT_CURSOR));
354: pack();
355: SwingUtilities.invokeLater(new Runnable() {
356: public void run() {
357: String version = VersionUtil.getVersion();
358: String newVersion = VersionUtil.getLatestVersion();
359: if (newVersion == null) {
360: status
361: .setText("Unable to check if a new version is available");
362: } else if (!version.equals(newVersion)) {
363: status.setText("Version " + newVersion
364: + " is available for download at: ");
365: link.setVisible(true);
366: } else {
367: status.setText("Your version is up to date!");
368: }
369: b.setEnabled(true);
370: setCursor(Cursor.getDefaultCursor());
371: validate();
372: pack();
373: }
374: });
375: }
376:
377: }
378: }
|