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.awt.BorderLayout; 44 import java.awt.Toolkit; 45 import java.awt.Color; 46 import java.awt.event.ItemEvent; 47 import java.awt.event.ItemListener; 48 import javax.swing.JComponent; 49 import javax.swing.JCheckBox; 50 import javax.swing.JComboBox; 51 import javax.swing.JTextField; 52 import javax.swing.JPanel; 53 import javax.swing.JLabel; 54 import javax.swing.JList; 55 import javax.swing.event.ListSelectionEvent; 56 import javax.swing.event.ListSelectionListener; 57 import javax.swing.text.BadLocationException; 58 import javax.swing.text.PlainDocument; 59 import javax.swing.text.AttributeSet; 60 import javax.swing.border.LineBorder; 61 import java.io.PrintWriter; 62 import java.util.NoSuchElementException; 63 import java.util.StringTokenizer; 64 65 public abstract class Option extends Node implements Modifier { 66 public Option(Group parent, String nodeName, String description) { 67 super(parent, nodeName, description); 68 } 69 70 public abstract boolean isDefault(); 71 72 public void modifyTest(TestEnvironment env, Object val) { 73 env.setModifier(this, val); 74 } 75 76 public void restoreTest(TestEnvironment env, Object val) { 77 env.removeModifier(this); 78 } 79 80 public abstract String getValString(); 81 82 public String getValString(Object v) { 83 return v.toString(); 84 } 85 86 public String getOptionString() { 87 return getTreeName()+"="+getValString(); 88 } 89 90 public String getOptionString(Object value) { 91 return getTreeName()+"="+getValString(value); 92 } 93 94 public String getAbbreviatedModifierDescription(Object value) { 95 return getNodeName()+"="+getValString(value); 96 } 97 98 public String getModifierValueName(Object val) { 99 return getValString(val); 100 } 101 102 public String setOption(String key, String value) { 103 if (key.length() != 0) { 104 return "Option name too specific"; 105 } 106 return setValueFromString(value); 107 } 108 109 public abstract String setValueFromString(String value); 110 111 public void write(PrintWriter pw) { 112 //if (!isDefault()) { 113 pw.println(getOptionString()); 114 //} 115 } 116 117 public String toString() { 118 return "Option("+getOptionString()+")"; 119 } 120 121 public static class Toggle extends Option { 122 public static final int Off = 0; 123 public static final int On = 1; 124 public static final int Both = 2; 125 126 private static final String valnames[] = {"Off", "On", "Both"}; 127 private static final Boolean valuelist[][] = { 128 BooleanIterator.FalseList, 129 BooleanIterator.TrueList, 130 BooleanIterator.FalseTrueList, 131 }; 132 133 int defaultvalue; 134 int value; 135 JPanel jp; 136 JComboBox jcb; 137 138 public Toggle(Group parent, String nodeName, String description, 139 int defaultvalue) 140 { 141 super(parent, nodeName, description); 142 if (defaultvalue != Off && 143 defaultvalue != On && 144 defaultvalue != Both) 145 { 146 throw new IllegalArgumentException("bad default"); 147 } 148 this.defaultvalue = this.value = defaultvalue; 149 } 150 151 public void restoreDefault() { 152 if (value != defaultvalue) { 153 value = defaultvalue; 154 updateGUI(); 155 } 156 } 157 158 public void updateGUI() { 159 if (jcb != null) { 160 jcb.setSelectedIndex(value); 161 } 162 } 163 164 public boolean isDefault() { 165 return (value == defaultvalue); 166 } 167 168 public Modifier.Iterator getIterator(TestEnvironment env) { 169 return new BooleanIterator(valuelist[value]); 170 } 171 172 public JComponent getJComponent() { 173 if (jp == null) { 174 jp = new JPanel(); 175 jp.setLayout(new BorderLayout()); 176 JLabel jl = new JLabel(getDescription()); 177 jp.add(jl, BorderLayout.WEST); 178 jcb = new JComboBox(valnames); 179 updateGUI(); 180 jcb.addItemListener(new ItemListener() { 181 public void itemStateChanged(ItemEvent e) { 182 if (e.getStateChange() == ItemEvent.SELECTED) { 183 JComboBox jcb = (JComboBox) e.getItemSelectable(); 184 value = jcb.getSelectedIndex(); 185 if (J2DBench.verbose.isEnabled()) { 186 System.out.println(getOptionString()); 187 } 188 } 189 } 190 }); 191 jp.add(jcb, BorderLayout.EAST); 192 } 193 return jp; 194 } 195 196 public String getAbbreviatedModifierDescription(Object value) { 197 String ret = getNodeName(); 198 if (value.equals(Boolean.FALSE)) { 199 ret = "!"+ret; 200 } 201 return ret; 202 } 203 204 public String getValString() { 205 return valnames[value]; 206 } 207 208 public String setValueFromString(String value) { 209 for (int i = 0; i < valnames.length; i++) { 210 if (valnames[i].equalsIgnoreCase(value)) { 211 if (this.value != i) { 212 this.value = i; 213 updateGUI(); 214 } 215 return null; 216 } 217 } 218 return "Bad value"; 219 } 220 } 221 222 public static class Enable extends Option { 223 boolean defaultvalue; 224 boolean value; 225 JCheckBox jcb; 226 227 public Enable(Group parent, String nodeName, String description, 228 boolean defaultvalue) 229 { 230 super(parent, nodeName, description); 231 this.defaultvalue = this.value = defaultvalue; 232 } 233 234 public boolean isEnabled() { 235 return value; 236 } 237 238 public void modifyTest(TestEnvironment env) { 239 // Used from within a Group.EnableSet group. 240 } 241 242 public void restoreTest(TestEnvironment env) { 243 // Used from within a Group.EnableSet group. 244 } 245 246 public void restoreDefault() { 247 if (value != defaultvalue) { 248 value = defaultvalue; 249 updateGUI(); 250 } 251 } 252 253 public void updateGUI() { 254 if (jcb != null) { 255 jcb.setSelected(value); 256 } 257 } 258 259 public boolean isDefault() { 260 return (value == defaultvalue); 261 } 262 263 public Modifier.Iterator getIterator(TestEnvironment env) { 264 return new BooleanIterator(value); 265 } 266 267 public JComponent getJComponent() { 268 if (jcb == null) { 269 jcb = new JCheckBox(getDescription()); 270 updateGUI(); 271 jcb.addItemListener(new ItemListener() { 272 public void itemStateChanged(ItemEvent e) { 273 value = (e.getStateChange() == ItemEvent.SELECTED); 274 if (J2DBench.verbose.isEnabled()) { 275 System.out.println(getOptionString()); 276 } 277 } 278 }); 279 } 280 return jcb; 281 } 282 283 public String getAbbreviatedModifierDescription(Object value) { 284 String ret = getNodeName(); 285 if (value.equals(Boolean.FALSE)) { 286 ret = "!"+ret; 287 } 288 return ret; 289 } 290 291 public String getValString() { 292 return (value ? "enabled" : "disabled"); 293 } 294 295 public String setValueFromString(String value) { 296 boolean newval; 297 if (value.equalsIgnoreCase("enabled")) { 298 newval = true; 299 } else if (value.equalsIgnoreCase("disabled")) { 300 newval = false; 301 } else { 302 return "Bad Value"; 303 } 304 if (this.value != newval) { 305 this.value = newval; 306 updateGUI(); 307 } 308 return null; 309 } 310 } 311 312 public static class Int extends Option { 313 int minvalue; 314 int maxvalue; 315 int defaultvalue; 316 int value; 317 JPanel jp; 318 JTextField jtf; 319 320 public Int(Group parent, String nodeName, String description, 321 int minvalue, int maxvalue, int defaultvalue) 322 { 323 super(parent, nodeName, description); 324 this.minvalue = minvalue; 325 this.maxvalue = maxvalue; 326 if (defaultvalue < minvalue || defaultvalue > maxvalue) { 327 throw new RuntimeException("bad value string: "+value); 328 } 329 this.defaultvalue = this.value = defaultvalue; 330 } 331 332 public int getIntValue() { 333 return value; 334 } 335 336 public void restoreDefault() { 337 if (value != defaultvalue) { 338 value = defaultvalue; 339 updateGUI(); 340 } 341 } 342 343 public void updateGUI() { 344 if (jtf != null) { 345 jtf.setText(getValString()); 346 } 347 } 348 349 public boolean isDefault() { 350 return (value == defaultvalue); 351 } 352 353 public Modifier.Iterator getIterator(TestEnvironment env) { 354 return new SwitchIterator(new Object[] { new Integer(value) }, 1); 355 } 356 357 public JComponent getJComponent() { 358 if (jp == null) { 359 jp = new JPanel(); 360 jp.setLayout(new BorderLayout()); 361 jp.add(new JLabel(getDescription()), BorderLayout.WEST); 362 jtf = new JTextField(10); 363 updateGUI(); 364 jtf.setDocument(new PlainDocument() { 365 public void insertString(int offs, String str, 366 AttributeSet a) 367 throws BadLocationException 368 { 369 if (str == null) { 370 return; 371 } 372 for (int i = 0; i < str.length(); i++) { 373 char c = str.charAt(i); 374 if (c < '0' || c > '9') { 375 Toolkit.getDefaultToolkit().beep(); 376 return; 377 } 378 } 379 String oldstr = jtf.getText(); 380 super.insertString(offs, str, a); 381 str = jtf.getText(); 382 if (setValueFromString(str) == null) { 383 if (J2DBench.verbose.isEnabled()) { 384 System.out.println(getOptionString()); 385 } 386 } else { 387 super.remove(0, super.getLength()); 388 super.insertString(0, oldstr, null); 389 Toolkit.getDefaultToolkit().beep(); 390 } 391 } 392 }); 393 jtf.setText(getValString()); 394 jp.add(jtf, BorderLayout.EAST); 395 } 396 return jp; 397 } 398 399 public String getValString() { 400 return Integer.toString(value); 401 } 402 403 public String setValueFromString(String value) { 404 int val; 405 try { 406 val = Integer.parseInt(value); 407 } catch (NumberFormatException e) { 408 return "Value not an integer ("+value+")"; 409 } 410 if (val < minvalue || val > maxvalue) { 411 return "Value out of range"; 412 } 413 if (this.value != val) { 414 this.value = val; 415 updateGUI(); 416 } 417 return null; 418 } 419 } 420 421 public static class ObjectList extends Option { 422 int size; 423 String optionnames[]; 424 Object optionvalues[]; 425 String abbrevnames[]; 426 String descnames[]; 427 int defaultenabled; 428 int enabled; 429 JPanel jp; 430 JList jlist; 431 int numrows; 432 433 public ObjectList(Group parent, String nodeName, String description, 434 String optionnames[], 435 Object optionvalues[], 436 String abbrevnames[], 437 String descnames[], 438 int defaultenabled) 439 { 440 this(parent, nodeName, description, 441 Math.min(Math.min(optionnames.length, 442 optionvalues.length), 443 Math.min(abbrevnames.length, 444 descnames.length)), 445 optionnames, optionvalues, 446 abbrevnames, descnames, defaultenabled); 447 } 448 449 public ObjectList(Group parent, String nodeName, String description, 450 int size, 451 String optionnames[], 452 Object optionvalues[], 453 String abbrevnames[], 454 String descnames[], 455 int defaultenabled) 456 { 457 super(parent, nodeName, description); 458 this.size = size; 459 this.optionnames = trim(optionnames, size); 460 this.optionvalues = trim(optionvalues, size); 461 this.abbrevnames = trim(abbrevnames, size); 462 this.descnames = trim(descnames, size); 463 this.enabled = this.defaultenabled = defaultenabled; 464 } 465 466 private static String[] trim(String list[], int size) { 467 if (list.length == size) { 468 return list; 469 } 470 String newlist[] = new String[size]; 471 System.arraycopy(list, 0, newlist, 0, size); 472 return newlist; 473 } 474 475 private static Object[] trim(Object list[], int size) { 476 if (list.length == size) { 477 return list; 478 } 479 Object newlist[] = new Object[size]; 480 System.arraycopy(list, 0, newlist, 0, size); 481 return newlist; 482 } 483 484 public void restoreDefault() { 485 if (enabled != defaultenabled) { 486 enabled = defaultenabled; 487 updateGUI(); 488 } 489 } 490 491 public void updateGUI() { 492 if (jlist != null) { 493 int enabled = this.enabled; 494 jlist.clearSelection(); 495 for (int curindex = 0; curindex < size; curindex++) { 496 if ((enabled & (1 << curindex)) != 0) { 497 jlist.addSelectionInterval(curindex, curindex); 498 } 499 } 500 } 501 } 502 503 public boolean isDefault() { 504 return (enabled == defaultenabled); 505 } 506 507 public Modifier.Iterator getIterator(TestEnvironment env) { 508 return new SwitchIterator(optionvalues, enabled); 509 } 510 511 public void setNumRows(int numrows) { 512 this.numrows = numrows; 513 } 514 515 public JComponent getJComponent() { 516 if (jp == null) { 517 jp = new JPanel(); 518 jp.setLayout(new BorderLayout()); 519 jp.add(new JLabel(getDescription()), BorderLayout.WEST); 520 jlist = new JList(descnames); 521 if (numrows > 0) { 522 try { 523 jlist.setLayoutOrientation(JList.VERTICAL_WRAP); 524 } catch (NoSuchMethodError e) { 525 } 526 jlist.setVisibleRowCount(numrows); 527 } 528 jlist.setBorder(new LineBorder(Color.black, 2)); 529 updateGUI(); 530 jlist.addListSelectionListener(new ListSelectionListener() { 531 public void valueChanged(ListSelectionEvent e) { 532 int flags = 0; 533 for (int curindex = 0; curindex < size; curindex++) { 534 JList list = (JList) e.getSource(); 535 if (list.isSelectedIndex(curindex)) { 536 flags |= (1 << curindex); 537 } 538 } 539 enabled = flags; 540 if (J2DBench.verbose.isEnabled()) { 541 System.out.println(getOptionString()); 542 } 543 } 544 }); 545 jp.add(jlist, BorderLayout.EAST); 546 } 547 return jp; 548 } 549 550 public String getValString() { 551 StringBuffer sb = new StringBuffer(); 552 for (int i = 0; i < size; i++) { 553 if ((enabled & (1 << i)) != 0) { 554 if (sb.length() > 0) { 555 sb.append(','); 556 } 557 sb.append(optionnames[i]); 558 } 559 } 560 return sb.toString(); 561 } 562 563 int findValueIndex(Object value) { 564 for (int i = 0; i < size; i++) { 565 if (optionvalues[i] == value) { 566 return i; 567 } 568 } 569 return -1; 570 } 571 572 public String getValString(Object value) { 573 return optionnames[findValueIndex(value)]; 574 } 575 576 public String getAbbreviatedModifierDescription(Object value) { 577 return abbrevnames[findValueIndex(value)]; 578 } 579 580 public String setValueFromString(String value) { 581 int enabled = 0; 582 StringTokenizer st = new StringTokenizer(value, ","); 583 while (st.hasMoreTokens()) { 584 String s = st.nextToken(); 585 try { 586 for (int i = 0; i < size; i++) { 587 if (optionnames[i].equals(s)) { 588 enabled |= (1 << i); 589 s = null; 590 break; 591 } 592 } 593 } catch (NumberFormatException e) { 594 } 595 if (s != null) { 596 return "Bad value in list ("+s+")"; 597 } 598 } 599 this.enabled = enabled; 600 updateGUI(); 601 return null; 602 } 603 } 604 605 public static class IntList extends ObjectList { 606 public IntList(Group parent, String nodeName, String description, 607 int values[], String abbrevnames[], String descnames[], 608 int defaultenabled) 609 { 610 super(parent, nodeName, description, 611 makeNames(values), makeValues(values), 612 abbrevnames, descnames, defaultenabled); 613 } 614 615 private static String[] makeNames(int intvalues[]) { 616 String names[] = new String[intvalues.length]; 617 for (int i = 0; i < intvalues.length; i++) { 618 names[i] = Integer.toString(intvalues[i]); 619 } 620 return names; 621 } 622 623 private static Object[] makeValues(int intvalues[]) { 624 Object values[] = new Object[intvalues.length]; 625 for (int i = 0; i < intvalues.length; i++) { 626 values[i] = new Integer(intvalues[i]); 627 } 628 return values; 629 } 630 } 631 632 public static class ObjectChoice extends Option { 633 int size; 634 String optionnames[]; 635 Object optionvalues[]; 636 String abbrevnames[]; 637 String descnames[]; 638 int defaultselected; 639 int selected; 640 JPanel jp; 641 JComboBox jcombo; 642 643 public ObjectChoice(Group parent, String nodeName, String description, 644 String optionnames[], 645 Object optionvalues[], 646 String abbrevnames[], 647 String descnames[], 648 int defaultselected) 649 { 650 this(parent, nodeName, description, 651 Math.min(Math.min(optionnames.length, 652 optionvalues.length), 653 Math.min(abbrevnames.length, 654 descnames.length)), 655 optionnames, optionvalues, 656 abbrevnames, descnames, defaultselected); 657 } 658 659 public ObjectChoice(Group parent, String nodeName, String description, 660 int size, 661 String optionnames[], 662 Object optionvalues[], 663 String abbrevnames[], 664 String descnames[], 665 int defaultselected) 666 { 667 super(parent, nodeName, description); 668 this.size = size; 669 this.optionnames = trim(optionnames, size); 670 this.optionvalues = trim(optionvalues, size); 671 this.abbrevnames = trim(abbrevnames, size); 672 this.descnames = trim(descnames, size); 673 this.selected = this.defaultselected = defaultselected; 674 } 675 676 private static String[] trim(String list[], int size) { 677 if (list.length == size) { 678 return list; 679 } 680 String newlist[] = new String[size]; 681 System.arraycopy(list, 0, newlist, 0, size); 682 return newlist; 683 } 684 685 private static Object[] trim(Object list[], int size) { 686 if (list.length == size) { 687 return list; 688 } 689 Object newlist[] = new Object[size]; 690 System.arraycopy(list, 0, newlist, 0, size); 691 return newlist; 692 } 693 694 public void restoreDefault() { 695 if (selected != defaultselected) { 696 selected = defaultselected; 697 updateGUI(); 698 } 699 } 700 701 public void updateGUI() { 702 if (jcombo != null) { 703 jcombo.setSelectedIndex(this.selected); 704 } 705 } 706 707 public boolean isDefault() { 708 return (selected == defaultselected); 709 } 710 711 public Modifier.Iterator getIterator(TestEnvironment env) { 712 return new SwitchIterator(optionvalues, 1 << selected); 713 } 714 715 public JComponent getJComponent() { 716 if (jp == null) { 717 jp = new JPanel(); 718 jp.setLayout(new BorderLayout()); 719 jp.add(new JLabel(getDescription()), BorderLayout.WEST); 720 jcombo = new JComboBox(descnames); 721 updateGUI(); 722 jcombo.addItemListener(new ItemListener() { 723 public void itemStateChanged(ItemEvent e) { 724 if (e.getStateChange() == ItemEvent.SELECTED) { 725 selected = jcombo.getSelectedIndex(); 726 if (J2DBench.verbose.isEnabled()) { 727 System.out.println(getOptionString()); 728 } 729 } 730 } 731 }); 732 jp.add(jcombo, BorderLayout.EAST); 733 } 734 return jp; 735 } 736 737 public Object getValue() { 738 return optionvalues[selected]; 739 } 740 741 public int getIntValue() { 742 return ((Integer) optionvalues[selected]).intValue(); 743 } 744 745 public boolean getBooleanValue() { 746 return ((Boolean) optionvalues[selected]).booleanValue(); 747 } 748 749 public String getValString() { 750 return optionnames[selected]; 751 } 752 753 int findValueIndex(Object value) { 754 for (int i = 0; i < size; i++) { 755 if (optionvalues[i] == value) { 756 return i; 757 } 758 } 759 return -1; 760 } 761 762 public String getValString(Object value) { 763 return optionnames[findValueIndex(value)]; 764 } 765 766 public String getAbbreviatedModifierDescription(Object value) { 767 return abbrevnames[findValueIndex(value)]; 768 } 769 770 public String setValue(int v) { 771 return setValue(new Integer(v)); 772 } 773 774 public String setValue(boolean v) { 775 return setValue(new Boolean(v)); 776 } 777 778 public String setValue(Object value) { 779 for (int i = 0; i < size; i++) { 780 if (optionvalues[i].equals(value)) { 781 this.selected = i; 782 updateGUI(); 783 return null; 784 } 785 } 786 return "Bad value"; 787 } 788 789 public String setValueFromString(String value) { 790 for (int i = 0; i < size; i++) { 791 if (optionnames[i].equals(value)) { 792 this.selected = i; 793 updateGUI(); 794 return null; 795 } 796 } 797 return "Bad value"; 798 } 799 } 800 801 public static class BooleanIterator implements Modifier.Iterator { 802 private Boolean list[]; 803 private int index; 804 805 public static final Boolean FalseList[] = { Boolean.FALSE }; 806 public static final Boolean TrueList[] = { Boolean.TRUE }; 807 public static final Boolean 808 FalseTrueList[] = { Boolean.FALSE, Boolean.TRUE }; 809 public static final Boolean 810 TrueFalseList[] = { Boolean.TRUE, Boolean.FALSE }; 811 812 public BooleanIterator(boolean v) { 813 this(v ? TrueList : FalseList); 814 } 815 816 public BooleanIterator(Boolean list[]) { 817 this.list = list; 818 } 819 820 public boolean hasNext() { 821 return (index < list.length); 822 } 823 824 public Object next() { 825 if (index >= list.length) { 826 throw new NoSuchElementException(); 827 } 828 return list[index++]; 829 } 830 831 public void remove() { 832 throw new UnsupportedOperationException(); 833 } 834 } 835 836 public static class SwitchIterator implements Modifier.Iterator { 837 private Object list[]; 838 private int enabled; 839 private int index; 840 841 public SwitchIterator(Object[] list, int enabled) { 842 this.list = list; 843 this.enabled = enabled; 844 } 845 846 public boolean hasNext() { 847 return ((1 << index) <= enabled); 848 } 849 850 public Object next() { 851 while ((enabled & (1 << index)) == 0) { 852 index++; 853 if (index >= list.length) { 854 throw new NoSuchElementException(); 855 } 856 } 857 return list[index++]; 858 } 859 860 public void remove() { 861 throw new UnsupportedOperationException(); 862 } 863 } 864 }