GNU Classpath (0.20) | |
Frames | No Frames |
1: /* JSplitPane.java -- 2: Copyright (C) 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.Component; 42: import java.awt.Graphics; 43: 44: import javax.accessibility.Accessible; 45: import javax.accessibility.AccessibleContext; 46: import javax.accessibility.AccessibleRole; 47: import javax.accessibility.AccessibleStateSet; 48: import javax.accessibility.AccessibleValue; 49: import javax.swing.plaf.SplitPaneUI; 50: 51: /** 52: * This class implements JSplitPane. It is used to divide two components. By 53: * dragging the SplitPane's divider, the user can resize the two components. 54: * Note that the divider cannot resize a component to smaller than it's 55: * minimum size. 56: */ 57: public class JSplitPane extends JComponent implements Accessible 58: { 59: /** 60: * DOCUMENT ME! 61: */ 62: // FIXME: This inner class is a complete stub and must be implemented 63: // properly. 64: protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent 65: implements AccessibleValue 66: { 67: private static final long serialVersionUID = -1788116871416305366L; 68: 69: /** 70: * Creates a new AccessibleJSplitPane object. 71: */ 72: protected AccessibleJSplitPane() 73: { 74: // Nothing to do here. 75: } 76: 77: /** 78: * DOCUMENT ME! 79: * 80: * @return DOCUMENT ME! 81: */ 82: public AccessibleStateSet getAccessibleStateSet() 83: { 84: return null; 85: } 86: 87: /** 88: * DOCUMENT ME! 89: * 90: * @return DOCUMENT ME! 91: */ 92: public AccessibleRole getAccessibleRole() 93: { 94: return null; 95: } 96: 97: /** 98: * DOCUMENT ME! 99: * 100: * @return DOCUMENT ME! 101: */ 102: public AccessibleValue getAccessibleValue() 103: { 104: return null; 105: } 106: 107: /** 108: * DOCUMENT ME! 109: * 110: * @return DOCUMENT ME! 111: */ 112: public Number getCurrentAccessibleValue() 113: { 114: return null; 115: } 116: 117: /** 118: * DOCUMENT ME! 119: * 120: * @param value0 DOCUMENT ME! 121: * 122: * @return DOCUMENT ME! 123: */ 124: public boolean setCurrentAccessibleValue(Number value0) 125: { 126: return false; 127: } 128: 129: /** 130: * DOCUMENT ME! 131: * 132: * @return DOCUMENT ME! 133: */ 134: public Number getMinimumAccessibleValue() 135: { 136: return null; 137: } 138: 139: /** 140: * DOCUMENT ME! 141: * 142: * @return DOCUMENT ME! 143: */ 144: public Number getMaximumAccessibleValue() 145: { 146: return null; 147: } 148: } 149: 150: private static final long serialVersionUID = -5634142046175988380L; 151: 152: /** The constraints string used to add components to the bottom. */ 153: public static final String BOTTOM = "bottom"; 154: 155: /** The property fired when the continuousLayout property changes. */ 156: public static final String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout"; 157: 158: /** The property fired when the divider property changes. */ 159: public static final String DIVIDER = "divider"; 160: 161: /** The property fired when the divider location property changes. */ 162: public static final String DIVIDER_LOCATION_PROPERTY = "dividerLocation"; 163: 164: /** The property fired when the divider size property changes. */ 165: public static final String DIVIDER_SIZE_PROPERTY = "dividerSize"; 166: 167: /** 168: * The value of the orientation when the components are split horizontally. 169: */ 170: public static final int HORIZONTAL_SPLIT = 1; 171: 172: /** The property fired when the last divider location property changes. */ 173: public static final String LAST_DIVIDER_LOCATION_PROPERTY = 174: "lastDividerLocation"; 175: 176: /** The constraints string used to add components to the left. */ 177: public static final String LEFT = "left"; 178: 179: /** The property fired when the one touch expandable property changes. */ 180: public static final String ONE_TOUCH_EXPANDABLE_PROPERTY = 181: "oneTouchExpandable"; 182: 183: /** The property fired when the orientation property changes. */ 184: public static final String ORIENTATION_PROPERTY = "orientation"; 185: 186: /** The property fired when the resize weight property changes. */ 187: public static final String RESIZE_WEIGHT_PROPERTY = "resizeWeight"; 188: 189: /** The constraints string used to add components to the right. */ 190: public static final String RIGHT = "right"; 191: 192: /** The constraints string used to add components to the top. */ 193: public static final String TOP = "top"; 194: 195: /** The value of the orientation when the components are split vertically. */ 196: public static final int VERTICAL_SPLIT = 0; 197: 198: /** Whether the JSplitPane uses continuous layout. */ 199: protected boolean continuousLayout; 200: 201: /** Whether the JSplitPane uses one touch expandable buttons. */ 202: protected boolean oneTouchExpandable = false; 203: 204: // This is the master dividerSize variable and sets the 205: // BasicSplitPaneDivider one accordingly 206: 207: /** The size of the divider. */ 208: protected int dividerSize = 10; 209: 210: /** The last location of the divider given by the UI. */ 211: protected int lastDividerLocation; 212: 213: /** The orientation of the JSplitPane. */ 214: protected int orientation; 215: 216: /** The component on the top or left. */ 217: protected Component leftComponent; 218: 219: /** The component on the right or bottom. */ 220: protected Component rightComponent; 221: 222: /** Determines how extra space should be allocated. */ 223: private transient double resizeWeight; 224: 225: /** 226: * Creates a new JSplitPane object with the given orientation, layout mode, 227: * and left and right components. 228: * 229: * @param newOrientation The orientation to use. 230: * @param newContinuousLayout The layout mode to use. 231: * @param newLeftComponent The left component. 232: * @param newRightComponent The right component. 233: * 234: * @throws IllegalArgumentException DOCUMENT ME! 235: */ 236: public JSplitPane(int newOrientation, boolean newContinuousLayout, 237: Component newLeftComponent, Component newRightComponent) 238: { 239: if (newOrientation != HORIZONTAL_SPLIT && newOrientation != VERTICAL_SPLIT) 240: throw new IllegalArgumentException("orientation is invalid."); 241: orientation = newOrientation; 242: continuousLayout = newContinuousLayout; 243: setLeftComponent(newLeftComponent); 244: setRightComponent(newRightComponent); 245: 246: updateUI(); 247: } 248: 249: /** 250: * Creates a new JSplitPane object using nonContinuousLayout mode, the given 251: * orientation and left and right components. 252: * 253: * @param newOrientation The orientation to use. 254: * @param newLeftComponent The left component. 255: * @param newRightComponent The right component. 256: */ 257: public JSplitPane(int newOrientation, Component newLeftComponent, 258: Component newRightComponent) 259: { 260: this(newOrientation, false, newLeftComponent, newRightComponent); 261: } 262: 263: /** 264: * Creates a new JSplitPane object with the given layout mode and 265: * orientation. 266: * 267: * @param newOrientation The orientation to use. 268: * @param newContinuousLayout The layout mode to use. 269: */ 270: public JSplitPane(int newOrientation, boolean newContinuousLayout) 271: { 272: this(newOrientation, newContinuousLayout, null, null); 273: } 274: 275: /** 276: * Creates a new JSplitPane object using a nonContinuousLayout mode and the 277: * given orientation. 278: * 279: * @param newOrientation The orientation to use. 280: */ 281: public JSplitPane(int newOrientation) 282: { 283: this(newOrientation, false, null, null); 284: } 285: 286: /** 287: * Creates a new JSplitPane object using HORIZONTAL_SPLIT and a 288: * nonContinuousLayout mode. 289: */ 290: public JSplitPane() 291: { 292: this(HORIZONTAL_SPLIT, false, new JButton("left button"), 293: new JButton("right button")); 294: } 295: 296: /** 297: * This method adds a component to the JSplitPane. The constraints object is 298: * a string that identifies where this component should go. If the 299: * constraints is not a known one, it will throw an 300: * IllegalArgumentException. The valid constraints are LEFT, TOP, RIGHT, 301: * BOTTOM and DIVIDER. 302: * 303: * @param comp The component to add. 304: * @param constraints The constraints string to use. 305: * @param index Where to place to component in the list of components. 306: * 307: * @throws IllegalArgumentException When the constraints is not a known 308: * identifier. 309: */ 310: protected void addImpl(Component comp, Object constraints, int index) 311: { 312: int left = 0; 313: int right = 1; 314: int div = 2; 315: int place; 316: if (constraints == null) 317: { 318: if (leftComponent == null) 319: constraints = LEFT; 320: else if (rightComponent == null) 321: constraints = RIGHT; 322: } 323: 324: if (constraints instanceof String) 325: { 326: String placement = (String) constraints; 327: 328: if (placement.equals(BOTTOM) || placement.equals(RIGHT)) 329: { 330: if (rightComponent != null) 331: remove(rightComponent); 332: rightComponent = comp; 333: } 334: else if (placement.equals(LEFT) || placement.equals(TOP)) 335: { 336: if (leftComponent != null) 337: remove(leftComponent); 338: leftComponent = comp; 339: } 340: else if (placement.equals(DIVIDER)) 341: constraints = null; 342: else 343: throw new 344: IllegalArgumentException("Constraints is not a known identifier."); 345: 346: super.addImpl(comp, constraints, index); 347: } 348: invalidate(); 349: layout(); 350: } 351: 352: /** 353: * DOCUMENT ME! 354: * 355: * @return DOCUMENT ME! 356: */ 357: public AccessibleContext getAccessibleContext() 358: { 359: if (accessibleContext == null) 360: accessibleContext = new AccessibleJSplitPane(); 361: 362: return accessibleContext; 363: } 364: 365: /** 366: * This method returns the bottom component. 367: * 368: * @return The bottom component. 369: */ 370: public Component getBottomComponent() 371: { 372: return rightComponent; 373: } 374: 375: /** 376: * This method returns the location of the divider. This method is passed to 377: * the UI. 378: * 379: * @return The location of the divider. 380: */ 381: public int getDividerLocation() 382: { 383: if (ui != null) 384: return ((SplitPaneUI) ui).getDividerLocation(this); 385: else 386: return -1; 387: } 388: 389: /** 390: * This method returns the size of the divider. 391: * 392: * @return The size of the divider. 393: */ 394: public int getDividerSize() 395: { 396: return dividerSize; 397: } 398: 399: /** 400: * This method returns the last divider location. 401: * 402: * @return The last divider location. 403: */ 404: public int getLastDividerLocation() 405: { 406: return lastDividerLocation; 407: } 408: 409: /** 410: * This method returns the left component. 411: * 412: * @return The left component. 413: */ 414: public Component getLeftComponent() 415: { 416: return leftComponent; 417: } 418: 419: /** 420: * This method returns the maximum divider location. This method is passed 421: * to the UI. 422: * 423: * @return DOCUMENT ME! 424: */ 425: public int getMaximumDividerLocation() 426: { 427: if (ui != null) 428: return ((SplitPaneUI) ui).getMaximumDividerLocation(this); 429: else 430: return -1; 431: } 432: 433: /** 434: * This method returns the minimum divider location. This method is passed 435: * to the UI. 436: * 437: * @return The minimum divider location. 438: */ 439: public int getMinimumDividerLocation() 440: { 441: if (ui != null) 442: return ((SplitPaneUI) ui).getMinimumDividerLocation(this); 443: else 444: return -1; 445: } 446: 447: /** 448: * This method returns the orientation that the JSplitPane is using. 449: * 450: * @return The current orientation. 451: */ 452: public int getOrientation() 453: { 454: return orientation; 455: } 456: 457: /** 458: * This method returns the current resize weight. 459: * 460: * @return The current resize weight. 461: */ 462: public double getResizeWeight() 463: { 464: return resizeWeight; 465: } 466: 467: /** 468: * This method returns the right component. 469: * 470: * @return The right component. 471: */ 472: public Component getRightComponent() 473: { 474: return rightComponent; 475: } 476: 477: /** 478: * This method returns the top component. 479: * 480: * @return The top component. 481: */ 482: public Component getTopComponent() 483: { 484: return leftComponent; 485: } 486: 487: /** 488: * This method returns the UI. 489: * 490: * @return The UI. 491: */ 492: public SplitPaneUI getUI() 493: { 494: return (SplitPaneUI) ui; 495: } 496: 497: /** 498: * This method returns true if the JSplitPane is using a continuousLayout. 499: * 500: * @return True if using a continuousLayout. 501: */ 502: public boolean isContinuousLayout() 503: { 504: return continuousLayout; 505: } 506: 507: /** 508: * This method returns true if the divider has one touch expandable buttons. 509: * 510: * @return True if one touch expandable is used. 511: */ 512: public boolean isOneTouchExpandable() 513: { 514: return oneTouchExpandable; 515: } 516: 517: /** 518: * This method returns true. 519: * 520: * @return true. 521: */ 522: public boolean isValidateRoot() 523: { 524: return true; 525: } 526: 527: /** 528: * This method overrides JComponent's paintChildren so the UI can be 529: * messaged when the children have finished painting. 530: * 531: * @param g The Graphics object to paint with. 532: */ 533: protected void paintChildren(Graphics g) 534: { 535: super.paintChildren(g); 536: if (ui != null) 537: ((SplitPaneUI) ui).finishedPaintingChildren(this, g); 538: } 539: 540: /** 541: * This method returns a String that describes this JSplitPane. The string 542: * is primarily used for debugging purposes. 543: * 544: * @return A String used for debugging purposes. 545: */ 546: protected String paramString() 547: { 548: return "JSplitPane"; 549: } 550: 551: /** 552: * This method removes the given component from the JSplitPane. 553: * 554: * @param component The Component to remove. 555: */ 556: public void remove(Component component) 557: { 558: if (component == leftComponent) 559: leftComponent = null; 560: else if (component == rightComponent) 561: rightComponent = null; 562: super.remove(component); 563: } 564: 565: /** 566: * This method removes the component at the given index. 567: * 568: * @param index The index of the component to remove. 569: */ 570: public void remove(int index) 571: { 572: Component component = getComponent(index); 573: if (component == leftComponent) 574: leftComponent = null; 575: else if (component == rightComponent) 576: rightComponent = null; 577: super.remove(index); 578: } 579: 580: /** 581: * This method removes all components from the JSplitPane. 582: */ 583: public void removeAll() 584: { 585: leftComponent = null; 586: rightComponent = null; 587: super.removeAll(); 588: } 589: 590: /** 591: * This method resets all children of the JSplitPane to their preferred 592: * sizes. 593: */ 594: public void resetToPreferredSizes() 595: { 596: if (ui != null) 597: ((SplitPaneUI) ui).resetToPreferredSizes(this); 598: } 599: 600: /** 601: * This method sets the bottom component. 602: * 603: * @param comp The Component to be placed at the bottom. 604: */ 605: public void setBottomComponent(Component comp) 606: { 607: if (comp != null) 608: add(comp, BOTTOM); 609: else 610: add(new JButton("right button"), BOTTOM); 611: } 612: 613: /** 614: * This method sets the layout mode for the JSplitPane. 615: * 616: * @param newContinuousLayout Whether the JSplitPane is in continuousLayout 617: * mode. 618: */ 619: public void setContinuousLayout(boolean newContinuousLayout) 620: { 621: if (newContinuousLayout != continuousLayout) 622: { 623: boolean oldValue = continuousLayout; 624: continuousLayout = newContinuousLayout; 625: firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldValue, 626: continuousLayout); 627: } 628: } 629: 630: /** 631: * This method sets the location of the divider. A value of 0 sets the 632: * divider to the farthest left. A value of 1 sets the divider to the 633: * farthest right. 634: * 635: * @param proportionalLocation A double that describes the location of the 636: * divider. 637: * 638: * @throws IllegalArgumentException DOCUMENT ME! 639: */ 640: public void setDividerLocation(double proportionalLocation) 641: { 642: if (proportionalLocation > 1 || proportionalLocation < 0) 643: throw new IllegalArgumentException 644: ("proportion has to be between 0 and 1."); 645: 646: int max = (orientation == HORIZONTAL_SPLIT) ? getWidth() : getHeight(); 647: setDividerLocation((int) (proportionalLocation * max)); 648: } 649: 650: /** 651: * This method sets the location of the divider. 652: * 653: * @param location The location of the divider. 654: */ 655: public void setDividerLocation(int location) 656: { 657: if (ui != null && location != getDividerLocation()) 658: { 659: int oldLocation = getDividerLocation(); 660: ((SplitPaneUI) ui).setDividerLocation(this, location); 661: firePropertyChange(DIVIDER_LOCATION_PROPERTY, oldLocation, location); 662: } 663: } 664: 665: /** 666: * This method sets the size of the divider. 667: * 668: * @param newSize The size of the divider. 669: */ 670: public void setDividerSize(int newSize) 671: { 672: if (newSize != dividerSize) 673: { 674: int oldSize = dividerSize; 675: dividerSize = newSize; 676: firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, dividerSize); 677: } 678: } 679: 680: // This doesn't appear to do anything when set from user side. 681: // so it probably is only used from the UI side to change the 682: // lastDividerLocation var. 683: 684: /** 685: * This method sets the last location of the divider. 686: * 687: * @param newLastLocation The last location of the divider. 688: */ 689: public void setLastDividerLocation(int newLastLocation) 690: { 691: if (newLastLocation != lastDividerLocation) 692: { 693: int oldValue = lastDividerLocation; 694: lastDividerLocation = newLastLocation; 695: firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldValue, 696: lastDividerLocation); 697: } 698: } 699: 700: /** 701: * This method sets the left component. 702: * 703: * @param comp The left component. 704: */ 705: public void setLeftComponent(Component comp) 706: { 707: if (comp != null) 708: add(comp, LEFT); 709: else 710: remove (leftComponent); 711: } 712: 713: /** 714: * This method sets whether the divider has one touch expandable buttons. 715: * The one touch expandable buttons can expand the size of either component 716: * to the maximum allowed size. 717: * 718: * @param newValue Whether the divider will have one touch expandable 719: * buttons. 720: */ 721: public void setOneTouchExpandable(boolean newValue) 722: { 723: if (newValue != oneTouchExpandable) 724: { 725: boolean oldValue = oneTouchExpandable; 726: oneTouchExpandable = newValue; 727: firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue, 728: oneTouchExpandable); 729: } 730: } 731: 732: /** 733: * This method sets the orientation of the JSplitPane. 734: * 735: * @param orientation The orientation of the JSplitPane. 736: * 737: * @throws IllegalArgumentException DOCUMENT ME! 738: */ 739: public void setOrientation(int orientation) 740: { 741: if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT) 742: throw new IllegalArgumentException 743: ("orientation must be one of VERTICAL_SPLIT, HORIZONTAL_SPLIT"); 744: if (orientation != this.orientation) 745: { 746: int oldOrientation = this.orientation; 747: this.orientation = orientation; 748: firePropertyChange(ORIENTATION_PROPERTY, oldOrientation, 749: this.orientation); 750: } 751: } 752: 753: /** 754: * This method determines how extra space will be distributed among the left 755: * and right components. A value of 0 will allocate all extra space to the 756: * right component. A value of 1 indicates that all extra space will go to 757: * the left component. A value in between 1 and 0 will split the space 758: * accordingly. 759: * 760: * @param value The resize weight. 761: */ 762: public void setResizeWeight(double value) 763: { 764: resizeWeight = value; 765: } 766: 767: /** 768: * This method sets the right component. 769: * 770: * @param comp The right component. 771: */ 772: public void setRightComponent(Component comp) 773: { 774: if (comp != null) 775: add(comp, RIGHT); 776: else 777: remove (rightComponent); 778: } 779: 780: /** 781: * This method sets the top component. 782: * 783: * @param comp The top component. 784: */ 785: public void setTopComponent(Component comp) 786: { 787: if (comp != null) 788: add(comp, TOP); 789: else 790: add(new JButton("left button"), TOP); 791: } 792: 793: /** 794: * This method sets the UI used by the JSplitPane. 795: * 796: * @param ui The UI to use. 797: */ 798: public void setUI(SplitPaneUI ui) 799: { 800: super.setUI(ui); 801: } 802: 803: /** 804: * This method resets the UI to the one specified by the current Look and 805: * Feel. 806: */ 807: public void updateUI() 808: { 809: setUI((SplitPaneUI) UIManager.getUI(this)); 810: invalidate(); 811: repaint(); 812: } 813: 814: /** 815: * This method returns a string identifier to determine which UI class it 816: * needs. 817: * 818: * @return A string that identifies it's UI class. 819: */ 820: public String getUIClassID() 821: { 822: return "SplitPaneUI"; 823: } 824: }
GNU Classpath (0.20) |