1 /*
   2  *
   3  * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  *
   9  *   - Redistributions of source code must retain the above copyright
  10  *     notice, this list of conditions and the following disclaimer.
  11  *
  12  *   - Redistributions in binary form must reproduce the above copyright
  13  *     notice, this list of conditions and the following disclaimer in the
  14  *     documentation and/or other materials provided with the distribution.
  15  *
  16  *   - Neither the name of Oracle nor the names of its
  17  *     contributors may be used to endorse or promote products derived
  18  *     from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 package java2d;
  33 
  34 
  35 import static java.awt.Color.BLACK;
  36 import static java.awt.Color.GREEN;
  37 import static java.awt.Color.RED;
  38 import java.awt.Component;
  39 import java.awt.Dimension;
  40 import java.awt.Font;
  41 import java.awt.GridBagLayout;
  42 import java.awt.GridLayout;
  43 import java.awt.event.ActionEvent;
  44 import java.awt.event.ActionListener;
  45 import java.util.Date;
  46 import java.util.logging.Level;
  47 import java.util.logging.Logger;
  48 import javax.swing.JButton;
  49 import javax.swing.JCheckBox;
  50 import javax.swing.JLabel;
  51 import javax.swing.JPanel;
  52 import javax.swing.JProgressBar;
  53 import javax.swing.JTextField;
  54 import javax.swing.SwingConstants;
  55 import javax.swing.SwingUtilities;
  56 import javax.swing.border.BevelBorder;
  57 import javax.swing.border.CompoundBorder;
  58 import javax.swing.border.EmptyBorder;
  59 
  60 
  61 /**
  62  * A separate window for running the J2Ddemo.  Go from tab to tab or demo to
  63  * demo.
  64  */
  65 @SuppressWarnings("serial")
  66 public class RunWindow extends JPanel implements Runnable, ActionListener {
  67     private final DemoInstVarsAccessor demoInstVars;
  68     private final JButton runB;
  69     private int delay = 10;
  70     private int numRuns = 20;
  71     private boolean exit;
  72     private final JCheckBox zoomCB = new JCheckBox("Zoom");
  73     private final JCheckBox printCB = new JCheckBox("Print");
  74     private boolean buffersFlag;
  75     private int bufBeg, bufEnd;
  76     private JTextField delayTextField, runsTextField;
  77     private Thread thread;
  78     private JProgressBar pb;
  79 
  80     @SuppressWarnings("LeakingThisInConstructor")
  81     public RunWindow(DemoInstVarsAccessor demoInstVars, RunWindowSettings runWndSetts) {
  82         this.demoInstVars = demoInstVars;
  83 
  84         delay = runWndSetts.getDelay();
  85         numRuns = runWndSetts.getNumRuns();
  86         exit = runWndSetts.getExit();
  87         zoomCB.setSelected(runWndSetts.isZoomCBSelected());
  88         printCB.setSelected(runWndSetts.isPrintCBSelected());
  89         buffersFlag = runWndSetts.getBuffersFlag();
  90         bufBeg = runWndSetts.getBufBeg();
  91         bufEnd = runWndSetts.getBufEnd();
  92 
  93         setLayout(new GridBagLayout());
  94         EmptyBorder eb = new EmptyBorder(5, 5, 5, 5);
  95         setBorder(new CompoundBorder(eb, new BevelBorder(BevelBorder.LOWERED)));
  96 
  97         Font font = new Font(Font.SERIF, Font.PLAIN, 10);
  98 
  99         runB = new JButton("Run");
 100         runB.setBackground(GREEN);
 101         runB.addActionListener(this);
 102         runB.setMinimumSize(new Dimension(70, 30));
 103         J2Ddemo.addToGridBag(this, runB, 0, 0, 1, 1, 0.0, 0.0);
 104 
 105         pb = new JProgressBar();
 106         pb.setPreferredSize(new Dimension(100, 30));
 107         pb.setMinimum(0);
 108         J2Ddemo.addToGridBag(this, pb, 1, 0, 2, 1, 1.0, 0.0);
 109 
 110         JPanel p1 = new JPanel(new GridLayout(2, 2));
 111         JPanel p2 = new JPanel();
 112         JLabel l = new JLabel("Runs:");
 113         l.setFont(font);
 114         l.setForeground(BLACK);
 115         p2.add(l);
 116         p2.add(runsTextField = new JTextField(String.valueOf(numRuns)));
 117         runsTextField.setPreferredSize(new Dimension(30, 20));
 118         runsTextField.addActionListener(this);
 119         p1.add(p2);
 120         p2 = new JPanel();
 121         l = new JLabel("Delay:");
 122         l.setFont(font);
 123         l.setForeground(BLACK);
 124         p2.add(l);
 125         p2.add(delayTextField = new JTextField(String.valueOf(delay)));
 126         delayTextField.setPreferredSize(new Dimension(30, 20));
 127         delayTextField.addActionListener(this);
 128         p1.add(p2);
 129 
 130         zoomCB.setHorizontalAlignment(SwingConstants.CENTER);
 131         zoomCB.setFont(font);
 132         printCB.setFont(font);
 133         p1.add(zoomCB);
 134         p1.add(printCB);
 135         printCB.addActionListener(this);
 136         J2Ddemo.addToGridBag(this, p1, 0, 1, 3, 1, 1.0, 1.0);
 137     }
 138 
 139     @Override
 140     public void actionPerformed(ActionEvent e) {
 141         if (e.getSource().equals(printCB)) {
 142             demoInstVars.getPrintCB().setSelected(printCB.isSelected());
 143         } else if (e.getSource().equals(delayTextField)) {
 144             delay = Integer.parseInt(delayTextField.getText().trim());
 145         } else if (e.getSource().equals(runsTextField)) {
 146             numRuns = Integer.parseInt(runsTextField.getText().trim());
 147         } else if ("Run".equals(e.getActionCommand())) {
 148             doRunAction();
 149         } else if ("Stop".equals(e.getActionCommand())) {
 150             stop();
 151         }
 152     }
 153 
 154     public void doRunAction() {
 155         runB.setText("Stop");
 156         runB.setBackground(RED);
 157         start();
 158     }
 159 
 160     public void start() {
 161         thread = new Thread(this);
 162         thread.setPriority(Thread.NORM_PRIORITY + 1);
 163         thread.setName("RunWindow");
 164         thread.start();
 165     }
 166 
 167     public synchronized void stop() {
 168         if (thread != null) {
 169             thread.interrupt();
 170         }
 171         thread = null;
 172         notifyAll();
 173     }
 174 
 175     @SuppressWarnings("SleepWhileHoldingLock")
 176     public void sleepPerTab() {
 177         for (int j = 0; j < delay + 1 && thread != null; j++) {
 178             for (int k = 0; k < 10 && thread != null; k++) {
 179                 try {
 180                     Thread.sleep(100);
 181                 } catch (Exception e) {
 182                 }
 183             }
 184             Runnable pbUpdateRunnable = new Runnable() {
 185 
 186                 @Override
 187                 public void run() {
 188                     pb.setValue(pb.getValue() + 1);
 189                 }
 190             };
 191             SwingUtilities.invokeLater(pbUpdateRunnable);
 192         }
 193     }
 194 
 195     private void printDemo(final DemoGroup dg) {
 196         Runnable printDemoRunnable = new Runnable() {
 197 
 198             @Override
 199             public void run() {
 200                 if (!demoInstVars.getControls().toolBarCB.isSelected()) {
 201                     demoInstVars.getControls().toolBarCB.setSelected(true);
 202                     dg.invalidate();
 203                 }
 204                 for (Component comp : dg.getPanel().getComponents()) {
 205                     DemoPanel dp = (DemoPanel) comp;
 206                     if (dp.tools != null) {
 207                         if (dp.surface.animating != null) {
 208                             if (dp.surface.animating.running()) {
 209                                 dp.tools.startStopB.doClick();
 210                             }
 211                         }
 212                         dp.tools.printB.doClick();
 213                     }
 214                 }
 215             }
 216         };
 217         invokeAndWait(printDemoRunnable);
 218     }
 219     private DemoGroup dg = null;
 220     private DemoPanel dp = null;
 221 
 222     @Override
 223     public void run() {
 224 
 225         System.out.println("\nJ2D Demo RunWindow : " + numRuns + " Runs, "
 226                 + delay + " second delay between tabs\n" + "java version: " + System.
 227                 getProperty("java.version") + "\n" + System.getProperty(
 228                 "os.name") + " " + System.getProperty("os.version") + "\n");
 229         Runtime r = Runtime.getRuntime();
 230 
 231         for (int runNum = 0; runNum < numRuns && thread != null; runNum++) {
 232 
 233             Date d = new Date();
 234             System.out.print("#" + runNum + " " + d.toString() + ", ");
 235             r.gc();
 236             float freeMemory = r.freeMemory();
 237             float totalMemory = r.totalMemory();
 238             System.out.println(((totalMemory - freeMemory) / 1024) + "K used");
 239 
 240             for (int i = 0; i < demoInstVars.getTabbedPane().getTabCount() && thread
 241                     != null; i++) {
 242 
 243                 final int mainTabIndex = i;
 244                 Runnable initDemoRunnable = new Runnable() {
 245 
 246                     @Override
 247                     public void run() {
 248                         pb.setValue(0);
 249                         pb.setMaximum(delay);
 250                         if (mainTabIndex != 0) {
 251                             dg = demoInstVars.getGroup()[mainTabIndex - 1];
 252                             dg.invalidate();
 253                         }
 254                         demoInstVars.getTabbedPane().setSelectedIndex(mainTabIndex);
 255                     }
 256                 };
 257                 invokeAndWait(initDemoRunnable);
 258 
 259                 if (i != 0 && (zoomCB.isSelected() || buffersFlag)) {
 260                     dp = (DemoPanel) dg.getPanel().getComponent(0);
 261                     if (dg.tabbedPane == null && dp.surface != null) {
 262                         Runnable mouseClickedRunnable = new Runnable() {
 263 
 264                             @Override
 265                             public void run() {
 266                                 dg.mouseClicked(dp.surface);
 267                             }
 268                         };
 269                         invokeAndWait(mouseClickedRunnable);
 270                     }
 271                     for (int j = 1; j < dg.tabbedPane.getTabCount() && thread
 272                             != null; j++) {
 273 
 274                         final int subTabIndex = j;
 275 
 276                         Runnable initPanelRunnable = new Runnable() {
 277 
 278                             @Override
 279                             public void run() {
 280                                 pb.setValue(0);
 281                                 pb.setMaximum(delay);
 282                                 dg.tabbedPane.setSelectedIndex(subTabIndex);
 283                             }
 284                         };
 285                         invokeAndWait(initPanelRunnable);
 286 
 287                         final JPanel p = dg.getPanel();
 288                         if (buffersFlag && p.getComponentCount() == 1) {
 289                             dp = (DemoPanel) p.getComponent(0);
 290                             if (dp.surface.animating != null) {
 291                                 dp.surface.animating.stop();
 292                             }
 293                             for (int k = bufBeg; k <= bufEnd && thread != null;
 294                                     k++) {
 295 
 296                                 final int cloneIndex = k;
 297                                 Runnable cloneRunnable = new Runnable() {
 298 
 299                                     @Override
 300                                     public void run() {
 301                                         dp.tools.cloneB.doClick();
 302                                         int n = p.getComponentCount();
 303                                         DemoPanel clone = (DemoPanel) p.
 304                                                 getComponent(n - 1);
 305                                         if (clone.surface.animating != null) {
 306                                             clone.surface.animating.stop();
 307                                         }
 308                                         clone.tools.issueRepaint = true;
 309                                         clone.tools.screenCombo.setSelectedIndex(
 310                                                 cloneIndex);
 311                                         clone.tools.issueRepaint = false;
 312                                     }
 313                                 };
 314                                 invokeAndWait(cloneRunnable);
 315                             }
 316                         }
 317                         if (printCB.isSelected()) {
 318                             printDemo(dg);
 319                         }
 320                         sleepPerTab();
 321                     }
 322                 } else if (i != 0 && printCB.isSelected()) {
 323                     printDemo(dg);
 324                     sleepPerTab();
 325                 } else {
 326                     sleepPerTab();
 327                 }
 328             }
 329             if (runNum + 1 == numRuns) {
 330                 System.out.println("Finished.");
 331                 if (exit && thread != null) {
 332                     System.out.println("System.exit(0).");
 333                     System.exit(0);
 334                 }
 335             }
 336         }
 337         Runnable resetRunnable = new Runnable() {
 338 
 339             @Override
 340             public void run() {
 341                 runB.setText("Run");
 342                 runB.setBackground(GREEN);
 343                 pb.setValue(0);
 344             }
 345         };
 346         invokeAndWait(resetRunnable);
 347 
 348         thread = null;
 349         dg = null;
 350         dp = null;
 351     }
 352 
 353     private static void invokeAndWait(Runnable run) {
 354         try {
 355             SwingUtilities.invokeAndWait(run);
 356         } catch (Exception e) {
 357             Logger.getLogger(RunWindow.class.getName()).log(Level.SEVERE,
 358                     "ERROR in invokeAndWait", e);
 359         }
 360     }
 361 
 362     /**
 363      * This class contains initial values for instance variables of 'RunWindow' class,
 364      * and its instance is used in creation of 'RunWindow' object. Values parsed from
 365      * certain command line options of the demo or from the demo applet parameters are
 366      * set to the fields of this class instance. It is a part of the fix which changed
 367      * static variables for instance variables in certain demo classes.
 368      *
 369      * This class is not thread safe, its instances must be accessed only from EDT.
 370      */
 371     public static class RunWindowSettings {
 372         private int delay = 10;
 373         private int numRuns = 20;
 374         private boolean exit;
 375         private boolean zoomCBIsSelected;
 376         private boolean printCBIsSelected;
 377         private boolean buffersFlag;
 378         private int bufBeg, bufEnd;
 379 
 380         public int getDelay() {
 381             return delay;
 382         }
 383 
 384         public void setDelay(int delay) {
 385             this.delay = delay;
 386         }
 387 
 388         public int getNumRuns() {
 389             return numRuns;
 390         }
 391 
 392         public void setNumRuns(int numRuns) {
 393             this.numRuns = numRuns;
 394         }
 395 
 396         public boolean getExit() {
 397             return exit;
 398         }
 399 
 400         public void setExit(boolean exit) {
 401             this.exit = exit;
 402         }
 403 
 404         public boolean isZoomCBSelected() {
 405             return zoomCBIsSelected;
 406         }
 407 
 408         public void setZoomCBSelected(boolean b) {
 409             zoomCBIsSelected = b;
 410         }
 411 
 412         public boolean isPrintCBSelected() {
 413             return printCBIsSelected;
 414         }
 415 
 416         public void setPrintCBIsSelected(boolean b) {
 417             printCBIsSelected = b;
 418         }
 419 
 420         public boolean getBuffersFlag() {
 421             return buffersFlag;
 422         }
 423 
 424         public void setBuffersFlag(boolean buffersFlag) {
 425             this.buffersFlag = buffersFlag;
 426         }
 427 
 428         public int getBufBeg() {
 429             return bufBeg;
 430         }
 431 
 432         public void setBufBeg(int bufBeg) {
 433             this.bufBeg = bufBeg;
 434         }
 435 
 436         public int getBufEnd() {
 437             return bufEnd;
 438         }
 439 
 440         public void setBufEnd(int bufEnd) {
 441             this.bufEnd = bufEnd;
 442         }
 443     }
 444 }