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