1 /*
2  * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  *   - Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  *
11  *   - Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *   - Neither the name of Oracle nor the names of its
16  *     contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * This source code is provided to illustrate the usage of a given feature
34  * or technique and has been deliberately simplified. Additional steps
35  * required for a production-quality application, such as security checks,
36  * input validation and proper error handling, might not be present in
37  * this sample code.
38  */
39 
40 
41 package j2dbench;
42 
43 import java.io.PrintWriter;
44 import java.io.FileReader;
45 import java.io.FileWriter;
46 import java.io.LineNumberReader;
47 import java.io.FileNotFoundException;
48 import java.io.IOException;
49 import java.io.File;
50 import java.awt.Frame;
51 import java.awt.Dimension;
52 import java.awt.BorderLayout;
53 import java.awt.event.ActionListener;
54 import java.awt.event.ActionEvent;
55 import java.awt.event.WindowAdapter;
56 import java.awt.event.WindowEvent;
57 import javax.swing.JFrame;
58 import javax.swing.JButton;
59 import javax.swing.JPanel;
60 import javax.swing.BoxLayout;
61 import javax.swing.JFileChooser;
62 import javax.swing.JOptionPane;
63 import javax.swing.SwingUtilities;
64 import javax.swing.WindowConstants;
65 
66 import java.text.SimpleDateFormat;
67 import java.util.Date;
68 
69 import j2dbench.tests.GraphicsTests;
70 import j2dbench.tests.ImageTests;
71 import j2dbench.tests.MiscTests;
72 import j2dbench.tests.RenderTests;
73 import j2dbench.tests.PixelTests;
74 import j2dbench.tests.iio.IIOTests;
75 import j2dbench.tests.cmm.CMMTests;
76 import j2dbench.tests.text.TextConstructionTests;
77 import j2dbench.tests.text.TextMeasureTests;
78 import j2dbench.tests.text.TextRenderTests;
79 import j2dbench.tests.text.TextTests;
80 
81 public class J2DBench {
82     static Group progoptroot;
83 
84     static Option.Enable verbose;
85     static Option.Enable printresults;
86 
87     static boolean looping = false;
88 
89     static JFrame guiFrame;
90 
91     static final SimpleDateFormat sdf =
92         new SimpleDateFormat("MM.dd.yyyy 'at' HH:mm aaa z");
93 
init()94     public static void init() {
95         progoptroot = new Group("prog", "Program Options");
96         progoptroot.setHidden();
97 
98         verbose =
99             new Option.Enable(progoptroot,
100                               "verbose", "Verbose print statements",
101                               false);
102         printresults =
103             new Option.Enable(progoptroot,
104                               "printresults", "Print results after each run",
105                               true);
106     }
107 
usage(int exitcode)108     public static void usage(int exitcode) {
109         System.out.println("usage: java -jar J2DBench.jar "+
110                            "[<optionname>=<value>]");
111         System.out.println("    "+
112                            "[-list] "+
113                            "[-gui | -interactive] "+
114                            "[-batch] "+
115                            "[-noshow] "+
116                            "[-nosave] "+
117                            "[-report:[NMKAUOsmuna/]] "+
118                            "[-usage | -help] "+
119                            "\n    "+
120                            "\n    "+
121                            "[-loadopts | -loadoptions] <optfile> "+
122                            "[-saveopts | -saveoptions] <optfile> "+
123                            "\n    "+
124                            "[-saveres | -saveresults] <resfile> "+
125                            "[-appres | -appendresults] <resfile> "+
126                            "\n    "+
127                            "[-title] <title> "+
128                            "[-desc | -description] <description> "+
129                            "\n    "+
130                            "[-loop] <duration> [-loopdef | -loopdefault] "+
131                            "");
132         System.out.println("        -list      "+
133                            "List the option settings on stdout");
134         System.out.println("        -gui       "+
135                            "Run the program in interactive mode (launch GUI)");
136         System.out.println("        -batch     "+
137                            "Run the program in batch mode (do not launch GUI)");
138         System.out.println("        -noshow    "+
139                            "Do not show output on the screen (batch mode)");
140         System.out.println("        -nosave    "+
141                            "Do not show save results to a file (batch mode)");
142         System.out.println("        -report    "+
143                            "Rate format to report 'X per Y' (default u/s)");
144         System.out.println("                   "+
145                            "  N = report in single units or ops");
146         System.out.println("                   "+
147                            "  M = report in millions of units or ops");
148         System.out.println("                   "+
149                            "  K = report in thousands of units or ops");
150         System.out.println("                   "+
151                            "  A = (auto) M or K as needed");
152         System.out.println("                   "+
153                            "  U = units as defined by the operation");
154         System.out.println("                   "+
155                            "  O = operations");
156         System.out.println("                   "+
157                            "  s = report by whole seconds");
158         System.out.println("                   "+
159                            "  m = report by milliseconds");
160         System.out.println("                   "+
161                            "  u = report by microseconds");
162         System.out.println("                   "+
163                            "  n = report by nanoseconds");
164         System.out.println("                   "+
165                            "  a = (auto) milli/micro/nanoseconds as needed");
166         System.out.println("                   "+
167                            "  / = invert (N/sec or secs/N)");
168         System.out.println("        -usage     "+
169                            "Print out this usage message");
170         System.out.println("        -saveres   "+
171                            "Save the results to the indicated file");
172         System.out.println("        -appres    "+
173                            "Append the results to the indicated file");
174         System.out.println("        -title     "+
175                            "Use the title for the saved results");
176         System.out.println("        -desc      "+
177                            "Use the description for the saved results");
178         System.out.println("        -loop      "+
179                            "Loop for the specified duration"+
180                            "\n                   "+
181                            "Duration specified as :"+
182                            "\n                     "+
183                            "<days>d / <hours>h / <minutes>m / dd:hh:mm");
184         System.out.println("        -loopdef   "+
185                            "Loop for a default duration of 72 hours");
186 
187         System.exit(exitcode);
188     }
189 
main(String[] argv)190     public static void main(String[] argv) {
191         init();
192         TestEnvironment.init();
193         Result.init();
194 
195         Destinations.init();
196         GraphicsTests.init();
197         RenderTests.init();
198         PixelTests.init();
199         ImageTests.init();
200         MiscTests.init();
201         TextTests.init();
202         TextRenderTests.init();
203         TextMeasureTests.init();
204         TextConstructionTests.init();
205         IIOTests.init();
206         CMMTests.init();
207 
208         boolean gui = true;
209         boolean showresults = true;
210         boolean saveresults = true;
211         String resfilename = null;
212         String title = null;
213         String desc = null;
214         boolean appendres = false;
215         long requiredLoopTime = 259200000; // 72 hrs * 60 * 60 * 1000
216         for (int i = 0; i < argv.length; i++) {
217             String arg = argv[i];
218             if (arg.equalsIgnoreCase("-list")) {
219                 PrintWriter pw = new PrintWriter(System.out);
220                 Node.Iterator iter = Group.root.getRecursiveChildIterator();
221                 while (iter.hasNext()) {
222                     Node n = iter.next();
223                     n.write(pw);
224                 }
225                 pw.flush();
226             } else if (arg.equalsIgnoreCase("-gui") ||
227                        arg.equalsIgnoreCase("-interactive"))
228             {
229                 gui = true;
230             } else if (arg.equalsIgnoreCase("-batch")) {
231                 gui = false;
232             } else if (arg.equalsIgnoreCase("-noshow")) {
233                 showresults = false;
234             } else if (arg.equalsIgnoreCase("-nosave")) {
235                 saveresults = false;
236             } else if (arg.equalsIgnoreCase("-usage") ||
237                        arg.equalsIgnoreCase("-help"))
238             {
239                 usage(0);
240             } else if (arg.equalsIgnoreCase("-loadoptions") ||
241                        arg.equalsIgnoreCase("-loadopts"))
242             {
243                 if (++i < argv.length) {
244                     String file = argv[i];
245                     String reason = loadOptions(file);
246                     if (reason != null) {
247                         System.err.println(reason);
248                         System.exit(1);
249                     }
250                 } else {
251                     usage(1);
252                 }
253             } else if (arg.equalsIgnoreCase("-saveoptions") ||
254                        arg.equalsIgnoreCase("-saveopts"))
255             {
256                 if (++i < argv.length) {
257                     String file = argv[i];
258                     String reason = saveOptions(file);
259                     if (reason != null) {
260                         System.err.println(reason);
261                         System.exit(1);
262                     }
263                 } else {
264                     usage(1);
265                 }
266             } else if (arg.equalsIgnoreCase("-saveresults") ||
267                        arg.equalsIgnoreCase("-saveres") ||
268                        arg.equalsIgnoreCase("-appendresults") ||
269                        arg.equalsIgnoreCase("-appres"))
270             {
271                 if (++i < argv.length) {
272                     resfilename = argv[i];
273                     appendres = arg.substring(0, 4).equalsIgnoreCase("-app");
274                 } else {
275                     usage(1);
276                 }
277             } else if (arg.equalsIgnoreCase("-title")) {
278                 if (++i < argv.length) {
279                     title = argv[i];
280                 } else {
281                     usage(1);
282                 }
283             } else if (arg.equalsIgnoreCase("-desc") ||
284                        arg.equalsIgnoreCase("-description"))
285             {
286                 if (++i < argv.length) {
287                     desc = argv[i];
288                 } else {
289                     usage(1);
290                 }
291             } else if (arg.equalsIgnoreCase("-loopdef") ||
292                        arg.equalsIgnoreCase("-loopdefault"))
293             {
294                 requiredLoopTime = 259200000; // 72 hrs * 60 * 60 * 1000
295                 J2DBench.looping = true;
296             } else if (arg.equalsIgnoreCase("-loop")) {
297 
298                 if (++i >= argv.length) {
299                     usage(1);
300                 }
301 
302                 J2DBench.looping = true;
303 
304                 /*
305                  * d or D    ->  Days
306                  * h or H    ->  Hours
307                  * m or M    ->  Minutes
308                  * dd:hh:mm  ->  Days:Hours:Minutes
309                  */
310 
311                 if (argv[i].indexOf(":") >= 0) {
312 
313                     String[] values = argv[i].split(":");
314                     int[] intVals = new int[3];
315 
316                     for(int j=0; j<values.length; j++) {
317                         try {
318                             intVals[j] = Integer.parseInt(values[j]);
319                         } catch(Exception e) {}
320                     }
321 
322                     System.out.println("\nLoop for " + intVals[0] +
323                                        " days " + intVals[1] +
324                                        " hours and " + intVals[2] + " minutes.\n");
325 
326                     requiredLoopTime = ((intVals[0] * 24 * 60 * 60) +
327                                         (intVals[1] * 60 * 60) +
328                                         (intVals[2] * 60)) * 1000;
329 
330                 } else {
331 
332                     String type = argv[i].substring(argv[i].length() - 1);
333 
334                     int multiplyWith = 1;
335 
336                     if (type.equalsIgnoreCase("d")) {
337                         multiplyWith = 24 * 60 * 60;
338                     } else if (type.equalsIgnoreCase("h")) {
339                         multiplyWith = 60 * 60;
340                     } else if (type.equalsIgnoreCase("m")) {
341                         multiplyWith = 60;
342                     } else {
343                         System.err.println("Invalid \"-loop\" option specified.");
344                         usage(1);
345                     }
346 
347                     int val = 1;
348                     try {
349                         val = Integer.parseInt(argv[i].substring(0, argv[i].length() - 1));
350                     } catch(Exception e) {
351                         System.err.println("Invalid \"-loop\" option specified.");
352                         usage(1);
353                     }
354 
355                     requiredLoopTime = val * multiplyWith * 1000;
356                 }
357 
358            } else if (arg.length() > 8 &&
359                         arg.substring(0, 8).equalsIgnoreCase("-report:"))
360            {
361                 String error = Result.parseRateOpt(arg.substring(8));
362                 if (error != null) {
363                      System.err.println("Invalid rate: "+error);
364                      usage(1);
365                 }
366             } else {
367                 String reason = Group.root.setOption(arg);
368                 if (reason != null) {
369                     System.err.println("Option "+arg+" ignored: "+reason);
370                 }
371             }
372         }
373         if (verbose.isEnabled()) {
374             Group.root.traverse(new Node.Visitor() {
375                 public void visit(Node node) {
376                     System.out.println(node);
377                 }
378             });
379         }
380 
381         if (gui) {
382             SwingUtilities.invokeLater(new Runnable() {
383                 public void run() {
384                     startGUI();
385                 }
386             });
387         } else {
388 
389             long start = System.currentTimeMillis();
390 
391             int nLoopCount = 1;
392 
393             if (saveresults) {
394                 if (title == null) {
395                     title = inputUserStr("title");
396                 }
397                 if (desc == null) {
398                     desc = inputUserStr("description");
399                 }
400             }
401 
402             PrintWriter writer = null;
403 
404             if (J2DBench.looping) {
405 
406                 System.out.println("\nAbout to run tests for : " +
407                                    (requiredLoopTime/1000) + " seconds.\n");
408 
409                 if(resfilename != null) {
410 
411                     try {
412                         String loopReportFileName =
413                             resfilename.substring(0, resfilename.lastIndexOf(".xml"));
414                         writer = new PrintWriter(
415                             new FileWriter(loopReportFileName + "_Loop.html"));
416                         writer.println("<html><head><title>" + title + "</title></head>");
417                         writer.println("<body bgcolor=\"#ffffff\"><hr size=\"1\">");
418                         writer.println("<center><h2>" + title + "</h2>");
419                         writer.println("</center><hr size=\"1\"><br>");
420                         writer.flush();
421                     } catch(IOException ioe) {
422                         ioe.printStackTrace();
423                         System.err.println("\nERROR : Could not create Loop-Report. Exit");
424                         System.exit(1);
425                     }
426                 }
427             }
428 
429             do {
430 
431                 Date loopStart = new Date();
432                 if (J2DBench.looping) {
433                     writer.println("<b>Loop # " + nLoopCount + "</b><br>");
434                     writer.println("<b>Start : </b>" + sdf.format(loopStart) + "<br>");
435                     writer.flush();
436                 }
437 
438                 runTests(showresults);
439                 if (saveresults) {
440                     if (resfilename != null) {
441                         lastResults.setTitle(title);
442                         lastResults.setDescription(desc);
443                         String reason = saveResults(resfilename, appendres);
444                         if (reason != null) {
445                             System.err.println(reason);
446                         }
447                     } else {
448                         saveResults(title, desc);
449                     }
450                 }
451 
452                 if (J2DBench.looping) {
453 
454                     Date loopEnd = new Date();
455 
456                     System.out.println("\n================================================================");
457                     System.out.println("-- Completed Loop " + nLoopCount + " at " + sdf.format(loopEnd) + " --");
458                     System.out.println("================================================================\n");
459 
460                     writer.println("<b>End : </b>" + sdf.format(loopEnd) + "<br>");
461                     writer.println("<b>Duration </b>: " + (loopEnd.getTime() - loopStart.getTime())/1000 + " Seconds<br>");
462                     writer.println("<b>Total : " + (loopEnd.getTime() - start)/1000 + " Seconds</b><br>");
463                     writer.println("</center><hr size=\"1\">");
464                     writer.flush();
465 
466                     if ((loopEnd.getTime() - start) > requiredLoopTime) {
467                         break;
468                     }
469 
470                     //Append results for looping - mode
471                     appendres = true;
472 
473                     nLoopCount++;
474                 }
475 
476             } while(J2DBench.looping);
477 
478             if (J2DBench.looping) {
479                 writer.println("</html>");
480                 writer.flush();
481                 writer.close();
482             }
483         }
484     }
485 
loadOptions(String filename)486     public static String loadOptions(String filename) {
487         FileReader fr;
488         try {
489             fr = new FileReader(filename);
490         } catch (FileNotFoundException e) {
491             return "file "+filename+" not found";
492         }
493         return loadOptions(fr, filename);
494     }
495 
loadOptions(File file)496     public static String loadOptions(File file) {
497         FileReader fr;
498         try {
499             fr = new FileReader(file);
500         } catch (FileNotFoundException e) {
501             return "file "+file.getPath()+" not found";
502         }
503         return loadOptions(fr, file.getPath());
504     }
505 
loadOptions(FileReader fr, String filename)506     public static String loadOptions(FileReader fr, String filename) {
507         LineNumberReader lnr = new LineNumberReader(fr);
508         Group.restoreAllDefaults();
509         String line;
510         try {
511             while ((line = lnr.readLine()) != null) {
512                 String reason = Group.root.setOption(line);
513                 if (reason != null) {
514                     System.err.println("Option "+line+
515                                        " at line "+lnr.getLineNumber()+
516                                        " ignored: "+reason);
517                 }
518             }
519         } catch (IOException e) {
520             Group.restoreAllDefaults();
521             return ("IO Error reading "+filename+
522                     " at line "+lnr.getLineNumber());
523         }
524         return null;
525     }
526 
saveOptions(String filename)527     public static String saveOptions(String filename) {
528         return saveOptions(new File(filename));
529     }
530 
saveOptions(File file)531     public static String saveOptions(File file) {
532         if (file.exists()) {
533             if (!file.isFile()) {
534                 return "Cannot save options to a directory!";
535             }
536             int ret = JOptionPane.showOptionDialog
537                 (guiFrame,
538                  new String[] {
539                      "The file '"+file.getName()+"' already exists!",
540                      "",
541                      "Do you wish to overwrite this file?",
542                  },
543                  "File exists!",
544                  JOptionPane.DEFAULT_OPTION,
545                  JOptionPane.WARNING_MESSAGE,
546                  null, new String[] {
547                      "Overwrite",
548                      "Cancel",
549                  }, "Cancel");
550             if (ret == 1) {
551                 return null;
552             }
553         }
554         FileWriter fw;
555         try {
556             fw = new FileWriter(file);
557         } catch (IOException e) {
558             return "Error opening option file "+file.getPath();
559         }
560         return saveOptions(fw, file.getPath());
561     }
562 
saveOptions(FileWriter fw, String filename)563     public static String saveOptions(FileWriter fw, String filename) {
564         PrintWriter pw = new PrintWriter(fw);
565         Group.writeAll(pw);
566         return null;
567     }
568 
569     public static JFileChooser theFC;
getFileChooser()570     public static JFileChooser getFileChooser() {
571         if (theFC == null) {
572             theFC = new JFileChooser(System.getProperty("user.dir"));
573         }
574         theFC.rescanCurrentDirectory();
575         return theFC;
576     }
577 
578     public static ResultSet lastResults;
saveOrDiscardLastResults()579     public static boolean saveOrDiscardLastResults() {
580         if (lastResults != null) {
581             int ret = JOptionPane.showConfirmDialog
582                 (guiFrame,
583                  "The results of the last test will be "+
584                  "discarded if you continue!  Do you want "+
585                  "to save them?",
586                  "Discard last results?",
587                  JOptionPane.YES_NO_CANCEL_OPTION);
588             if (ret == JOptionPane.CANCEL_OPTION) {
589                 return false;
590             } else if (ret == JOptionPane.YES_OPTION) {
591                 if (saveResults()) {
592                     lastResults = null;
593                 } else {
594                     return false;
595                 }
596             }
597         }
598         return true;
599     }
600 
inputUserStr(String type)601     public static String inputUserStr(String type) {
602         return JOptionPane.showInputDialog("Enter a "+
603                                            type+
604                                            " for this result set:");
605     }
606 
saveResults()607     public static boolean saveResults() {
608         return saveResults(inputUserStr("title"), inputUserStr("description"));
609     }
610 
saveResults(String title, String desc)611     public static boolean saveResults(String title, String desc) {
612         lastResults.setTitle(title);
613         lastResults.setDescription(desc);
614         JFileChooser fc = getFileChooser();
615         int ret = fc.showSaveDialog(guiFrame);
616         if (ret == JFileChooser.APPROVE_OPTION) {
617             File file = fc.getSelectedFile();
618             boolean append = false;
619             if (file.exists()) {
620                 if (!file.isFile()) {
621                     System.err.println("Cannot save results to a directory!");
622                     return false;
623                 }
624                 ret = JOptionPane.showOptionDialog
625                     (guiFrame,
626                      new String[] {
627                          "The file '"+file.getName()+"' already exists!",
628                          "",
629                          "Do you wish to overwrite or append to this file?",
630                      },
631                      "File exists!",
632                      JOptionPane.DEFAULT_OPTION,
633                      JOptionPane.WARNING_MESSAGE,
634                      null, new String[] {
635                          "Overwrite",
636                          "Append",
637                          "Cancel",
638                      }, "Cancel");
639                 if (ret == 0) {
640                     append = false;
641                 } else if (ret == 1) {
642                     append = true;
643                 } else {
644                     return false;
645                 }
646             }
647             String reason = saveResults(file, append);
648             if (reason == null) {
649                 return true;
650             } else {
651                 System.err.println(reason);
652             }
653         }
654         return false;
655     }
656 
saveResults(String filename, boolean append)657     public static String saveResults(String filename, boolean append) {
658         FileWriter fw;
659         try {
660             fw = new FileWriter(filename, append);
661         } catch (IOException e) {
662             return "Error opening results file "+filename;
663         }
664         return saveResults(fw, filename, append);
665     }
666 
saveResults(File file, boolean append)667     public static String saveResults(File file, boolean append) {
668         FileWriter fw;
669         try {
670             fw = new FileWriter(file, append);
671         } catch (IOException e) {
672             return "Error opening results file "+file.getName();
673         }
674         return saveResults(fw, file.getName(), append);
675     }
676 
saveResults(FileWriter fw, String filename, boolean append)677     public static String saveResults(FileWriter fw, String filename,
678                                      boolean append)
679     {
680         PrintWriter pw = new PrintWriter(fw);
681         if (!append) {
682             pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
683             pw.println("<!--For Entertainment Purposes Only-->");
684         }
685         pw.println();
686         lastResults.write(pw);
687         pw.flush();
688         pw.close();
689         return null;
690     }
691 
startGUI()692     public static void startGUI() {
693         final JFrame f = new JFrame("J2DBench") {
694             public Dimension getPreferredSize() {
695                 Dimension pref = super.getPreferredSize();
696                 pref.width = Math.max(pref.width, 800);
697                 pref.height = Math.max(pref.height, 600);
698                 return pref;
699             }
700         };
701         guiFrame = f;
702         f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
703         f.getContentPane().setLayout(new BorderLayout());
704         f.getContentPane().add(Group.root.getJComponent(), BorderLayout.CENTER);
705         JPanel p = new JPanel();
706         p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
707         JButton b = new JButton("Run Tests...");
708         b.addActionListener(new ActionListener() {
709             public void actionPerformed(ActionEvent e) {
710                 if (!saveOrDiscardLastResults()) {
711                     return;
712                 }
713                 if (verbose.isEnabled()) {
714                     System.out.println(e);
715                     System.out.println("running tests...");
716                 }
717                 new Thread(new Runnable() {
718                     public void run() {
719                         runTests(true);
720                     }
721                 }).start();
722                 if (verbose.isEnabled()) {
723                     System.out.println("done");
724                 }
725             }
726         });
727         p.add(b);
728 
729         b = new JButton("Load Options");
730         b.addActionListener(new ActionListener() {
731             public void actionPerformed(ActionEvent e) {
732                 JFileChooser fc = getFileChooser();
733                 int ret = fc.showOpenDialog(f);
734                 if (ret == JFileChooser.APPROVE_OPTION) {
735                     String reason = loadOptions(fc.getSelectedFile());
736                     if (reason != null) {
737                         System.err.println(reason);
738                     }
739                 }
740             }
741         });
742         p.add(b);
743 
744         b = new JButton("Save Options");
745         b.addActionListener(new ActionListener() {
746             public void actionPerformed(ActionEvent e) {
747                 JFileChooser fc = getFileChooser();
748                 int ret = fc.showSaveDialog(f);
749                 if (ret == JFileChooser.APPROVE_OPTION) {
750                     String reason = saveOptions(fc.getSelectedFile());
751                     if (reason != null) {
752                         System.err.println(reason);
753                     }
754                 }
755             }
756         });
757         p.add(b);
758 
759         b = new JButton("Save Results");
760         b.addActionListener(new ActionListener() {
761             public void actionPerformed(ActionEvent e) {
762                 if (saveResults()) {
763                     lastResults = null;
764                 }
765             }
766         });
767         p.add(b);
768 
769         b = new JButton("Quit");
770         b.addActionListener(new ActionListener() {
771             public void actionPerformed(ActionEvent e) {
772                 if (!saveOrDiscardLastResults()) {
773                     return;
774                 }
775                 System.exit(0);
776             }
777         });
778         p.add(b);
779 
780         f.getContentPane().add(p, BorderLayout.SOUTH);
781         f.pack();
782         f.setLocationRelativeTo(null);
783         f.show();
784     }
785 
runTests(boolean showresults)786     public static void runTests(boolean showresults) {
787         final TestEnvironment env = new TestEnvironment();
788         Frame f = null;
789         if (showresults) {
790             f = new Frame("J2DBench test run");
791             f.addWindowListener(new WindowAdapter() {
792                 public void windowClosing(WindowEvent e) {
793                     env.stop();
794                 }
795             });
796             f.add(env.getCanvas());
797             f.pack();
798             f.show();
799         }
800         for (int i = 0; i < 5; i++) {
801             env.idle();
802         }
803         env.runAllTests();
804         if (showresults) {
805             f.hide();
806             f.dispose();
807         }
808         lastResults = env.results;
809         if (J2DBench.printresults.isEnabled()) {
810             System.out.println();
811         }
812         System.out.println("All test results:");
813         env.summarize();
814         System.out.println();
815     }
816 }
817