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 41package j2dbench; 42 43import java.io.PrintWriter; 44import javax.swing.BoxLayout; 45import javax.swing.JComponent; 46import javax.swing.JPanel; 47import javax.swing.JScrollPane; 48import javax.swing.JTabbedPane; 49import javax.swing.border.TitledBorder; 50import java.util.NoSuchElementException; 51 52import j2dbench.ui.CompactLayout; 53import j2dbench.ui.EnableButton; 54 55public 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} 356