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