1 /*
   2  * Copyright (c) 2002, 2011, 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 javax.swing.BoxLayout;
  45 import javax.swing.JComponent;
  46 import javax.swing.JPanel;
  47 import javax.swing.JTabbedPane;
  48 import javax.swing.border.TitledBorder;
  49 import java.util.NoSuchElementException;
  50 
  51 import j2dbench.ui.CompactLayout;
  52 import j2dbench.ui.EnableButton;
  53 
  54 public class Group extends Node {
  55     public static Group root = new Group();
  56 
  57     private Node children;
  58     private boolean tabbed;
  59     private boolean hidden;
  60     private boolean horizontal;
  61     private Boolean bordered;
  62     private int tabPlacement;
  63 
  64     private Group() {
  65         setTabbed(JTabbedPane.LEFT);
  66     }
  67 
  68     public Group(String nodeName, String description) {
  69         this(root, nodeName, description);
  70     }
  71 
  72     public Group(Group parent, String nodeName, String description) {
  73         super(parent, nodeName, description);
  74     }
  75 
  76     public void addChild(Node child) {
  77         Node prev = null;
  78         for (Node node = children; node != null; node = node.getNext()) {
  79             if (node.getNodeName().equalsIgnoreCase(child.getNodeName())) {
  80                 throw new RuntimeException("duplicate child added");
  81             }
  82             prev = node;
  83         }
  84         if (prev == null) {
  85             children = child;
  86         } else {
  87             prev.setNext(child);
  88         }
  89     }
  90 
  91     public Node.Iterator getChildIterator() {
  92         return new ChildIterator();
  93     }
  94 
  95     public Node.Iterator getRecursiveChildIterator() {
  96         return new RecursiveChildIterator();
  97     }
  98 
  99     public Node getFirstChild() {
 100         return children;
 101     }
 102 
 103     public boolean isBordered() {
 104         if (bordered == null) {
 105             return (getParent() == null || !getParent().isTabbed());
 106         }
 107         return bordered.booleanValue();
 108     }
 109 
 110     public boolean isTabbed() {
 111         return tabbed;
 112     }
 113 
 114     public boolean isHidden() {
 115         return hidden;
 116     }
 117 
 118     public boolean isHorizontal() {
 119         return horizontal;
 120     }
 121 
 122     public void setBordered(boolean b) {
 123         bordered = b ? Boolean.TRUE : Boolean.FALSE;
 124     }
 125 
 126     public void setTabbed() {
 127         setTabbed(JTabbedPane.TOP);
 128     }
 129 
 130     public void setTabbed(int tabPlacement) {
 131         this.tabbed = true;
 132         this.tabPlacement = tabPlacement;
 133     }
 134 
 135     public void setHidden() {
 136         hidden = true;
 137     }
 138 
 139     public void setHorizontal() {
 140         horizontal = true;
 141     }
 142 
 143     public void traverse(Visitor v) {
 144         super.traverse(v);
 145         for (Node node = children; node != null; node = node.getNext()) {
 146             node.traverse(v);
 147         }
 148     }
 149 
 150     public void restoreDefault() {
 151     }
 152 
 153     public String setOption(String key, String value) {
 154         int index = key.indexOf('.');
 155         String subkey;
 156         if (index < 0) {
 157             subkey = "";
 158         } else {
 159             subkey = key.substring(index+1);
 160             key = key.substring(0, index);
 161         }
 162         for (Node node = children; node != null; node = node.getNext()) {
 163             if (node.getNodeName().equalsIgnoreCase(key)) {
 164                 return node.setOption(subkey, value);
 165             }
 166         }
 167         return "Key failed to match an existing option";
 168     }
 169 
 170     public void write(PrintWriter pw) {
 171     }
 172 
 173     public JComponent getJComponent() {
 174         if (isHidden()) {
 175             return null;
 176         } else if (isTabbed()) {
 177             JTabbedPane jtp = new JTabbedPane(tabPlacement);
 178             for (Node node = children; node != null; node = node.getNext()) {
 179                 JComponent comp = node.getJComponent();
 180                 if (comp != null) {
 181                     jtp.addTab(node.getDescription(), comp);
 182                 }
 183             }
 184             return jtp;
 185         } else {
 186             JPanel p = new JPanel();
 187             p.setLayout(new BoxLayout(p,
 188                                       horizontal
 189                                       ? BoxLayout.X_AXIS
 190                                       : BoxLayout.Y_AXIS));
 191             p.setLayout(new CompactLayout(horizontal));
 192             if (getDescription() != null && isBordered()) {
 193                 p.setBorder(new TitledBorder(getDescription()));
 194                 addEnableButtons(p);
 195             }
 196             for (Node node = children; node != null; node = node.getNext()) {
 197                 JComponent comp = node.getJComponent();
 198                 if (comp != null) {
 199                     p.add(comp);
 200                 }
 201             }
 202             return p;
 203         }
 204     }
 205 
 206     public void addEnableButtons(JPanel p) {
 207         p.add(new EnableButton(this, EnableButton.DEFAULT));
 208         p.add(new EnableButton(this, EnableButton.CLEAR));
 209         p.add(new EnableButton(this, EnableButton.INVERT));
 210         p.add(new EnableButton(this, EnableButton.SET));
 211     }
 212 
 213     public static void restoreAllDefaults() {
 214         root.traverse(new Visitor() {
 215             public void visit(Node node) {
 216                 node.restoreDefault();
 217             }
 218         });
 219     }
 220 
 221     public static void writeAll(final PrintWriter pw) {
 222         root.traverse(new Visitor() {
 223             public void visit(Node node) {
 224                 node.write(pw);
 225             }
 226         });
 227         pw.flush();
 228     }
 229 
 230     public static String setOption(String s) {
 231         int index = s.indexOf('=');
 232         if (index < 0) {
 233             return "No value specified";
 234         }
 235         String key = s.substring(0, index);
 236         String value = s.substring(index+1);
 237         return root.setOption(key, value);
 238     }
 239 
 240     public String toString() {
 241         return "Group("+getTreeName()+")";
 242     }
 243 
 244     public class ChildIterator implements Node.Iterator {
 245         protected Node cur = getFirstChild();
 246 
 247         public boolean hasNext() {
 248             return (cur != null);
 249         }
 250 
 251         public Node next() {
 252             Node ret = cur;
 253             if (ret == null) {
 254                 throw new NoSuchElementException();
 255             }
 256             cur = cur.getNext();
 257             return ret;
 258         }
 259     }
 260 
 261     public class RecursiveChildIterator extends ChildIterator {
 262         Node.Iterator subiterator;
 263 
 264         public boolean hasNext() {
 265             while (true) {
 266                 if (subiterator != null && subiterator.hasNext()) {
 267                     return true;
 268                 }
 269                 if (cur instanceof Group) {
 270                     subiterator = ((Group) cur).getRecursiveChildIterator();
 271                     cur = cur.getNext();
 272                 } else {
 273                     subiterator = null;
 274                     return super.hasNext();
 275                 }
 276             }
 277         }
 278 
 279         public Node next() {
 280             if (subiterator != null) {
 281                 return subiterator.next();
 282             } else {
 283                 return super.next();
 284             }
 285         }
 286     }
 287 
 288     public static class EnableSet extends Group implements Modifier {
 289         public EnableSet() {
 290             super();
 291         }
 292 
 293         public EnableSet(Group parent, String nodeName, String description) {
 294             super(parent, nodeName, description);
 295         }
 296 
 297         public Modifier.Iterator getIterator(TestEnvironment env) {
 298             return new EnableIterator();
 299         }
 300 
 301         public void modifyTest(TestEnvironment env, Object val) {
 302             ((Option.Enable) val).modifyTest(env);
 303             env.setModifier(this, val);
 304         }
 305 
 306         public void restoreTest(TestEnvironment env, Object val) {
 307             ((Option.Enable) val).restoreTest(env);
 308             env.removeModifier(this);
 309         }
 310 
 311         public String getAbbreviatedModifierDescription(Object val) {
 312             Option.Enable oe = (Option.Enable) val;
 313             return oe.getAbbreviatedModifierDescription(Boolean.TRUE);
 314         }
 315 
 316         public String getModifierValueName(Object val) {
 317             Option.Enable oe = (Option.Enable) val;
 318             return oe.getModifierValueName(Boolean.TRUE);
 319         }
 320 
 321         public class EnableIterator implements Modifier.Iterator {
 322             Node.Iterator childiterator = getRecursiveChildIterator();
 323             Option.Enable curval;
 324 
 325             public boolean hasNext() {
 326                 if (curval != null) {
 327                     return true;
 328                 }
 329                 while (childiterator.hasNext()) {
 330                     Node node = childiterator.next();
 331                     if (node instanceof Option.Enable) {
 332                         curval = (Option.Enable) node;
 333                         if (curval.isEnabled()) {
 334                             return true;
 335                         }
 336                         curval = null;
 337                     }
 338                 }
 339                 return false;
 340             }
 341 
 342             public Object next() {
 343                 if (curval == null) {
 344                     if (!hasNext()) {
 345                         throw new NoSuchElementException();
 346                     }
 347                 }
 348                 Object ret = curval;
 349                 curval = null;
 350                 return ret;
 351             }
 352         }
 353     }
 354 }