| 1 7 8 9 package javax.swing.plaf.basic; 10 11 12 import sun.swing.DefaultLookup; 13 import sun.swing.UIAction; 14 import javax.swing.*; 15 import javax.swing.border.Border ; 16 import javax.swing.event.*; 17 import java.awt.*; 18 import java.awt.event.*; 19 import java.awt.peer.ComponentPeer; 20 import java.awt.peer.LightweightPeer; 21 import java.beans.*; 22 import java.util.*; 23 import javax.swing.plaf.ActionMapUIResource ; 24 import javax.swing.plaf.SplitPaneUI ; 25 import javax.swing.plaf.ComponentUI ; 26 import javax.swing.plaf.UIResource ; 27 28 29 37 public class BasicSplitPaneUI extends SplitPaneUI  38 { 39 43 protected static final String NON_CONTINUOUS_DIVIDER = 44 "nonContinuousDivider"; 45 46 47 51 protected static int KEYBOARD_DIVIDER_MOVE_OFFSET = 3; 52 53 54 58 protected JSplitPane splitPane; 59 60 61 64 protected BasicHorizontalLayoutManager layoutManager; 65 66 67 70 protected BasicSplitPaneDivider divider; 71 72 73 76 protected PropertyChangeListener propertyChangeListener; 77 78 79 82 protected FocusListener focusListener; 83 84 private Handler handler; 85 86 87 91 private static Set managingFocusForwardTraversalKeys; 92 93 97 private static Set managingFocusBackwardTraversalKeys; 98 99 100 103 protected int dividerSize; 104 105 106 110 protected Component nonContinuousLayoutDivider; 111 112 113 117 protected boolean draggingHW; 118 119 120 123 protected int beginDragDividerLocation; 124 125 126 134 @Deprecated  135 protected KeyStroke upKey; 136 144 @Deprecated  145 protected KeyStroke downKey; 146 154 @Deprecated  155 protected KeyStroke leftKey; 156 164 @Deprecated  165 protected KeyStroke rightKey; 166 174 @Deprecated  175 protected KeyStroke homeKey; 176 184 @Deprecated  185 protected KeyStroke endKey; 186 194 @Deprecated  195 protected KeyStroke dividerResizeToggleKey; 196 197 205 @Deprecated  206 protected ActionListener keyboardUpLeftListener; 207 215 @Deprecated  216 protected ActionListener keyboardDownRightListener; 217 225 @Deprecated  226 protected ActionListener keyboardHomeListener; 227 235 @Deprecated  236 protected ActionListener keyboardEndListener; 237 245 @Deprecated  246 protected ActionListener keyboardResizeToggleListener; 247 248 249 private int orientation; 251 private int lastDragLocation; 252 private boolean continuousLayout; 253 private boolean dividerKeyboardResize; 254 private boolean dividerLocationIsSet; private Color dividerDraggingColor; 258 private boolean rememberPaneSizes; 259 260 private boolean keepHidden = false; 262 263 264 boolean painted; 268 269 boolean ignoreDividerLocationChange; 270 271 272 275 public static ComponentUI createUI(JComponent x) { 276 return new BasicSplitPaneUI (); 277 } 278 279 static void loadActionMap(LazyActionMap map) { 280 map.put(new Actions(Actions.NEGATIVE_INCREMENT)); 281 map.put(new Actions(Actions.POSITIVE_INCREMENT)); 282 map.put(new Actions(Actions.SELECT_MIN)); 283 map.put(new Actions(Actions.SELECT_MAX)); 284 map.put(new Actions(Actions.START_RESIZE)); 285 map.put(new Actions(Actions.TOGGLE_FOCUS)); 286 map.put(new Actions(Actions.FOCUS_OUT_FORWARD)); 287 map.put(new Actions(Actions.FOCUS_OUT_BACKWARD)); 288 } 289 290 291 292 295 public void installUI(JComponent c) { 296 splitPane = (JSplitPane) c; 297 dividerLocationIsSet = false; 298 dividerKeyboardResize = false; 299 keepHidden = false; 300 installDefaults(); 301 installListeners(); 302 installKeyboardActions(); 303 setLastDragLocation(-1); 304 } 305 306 307 310 protected void installDefaults(){ 311 LookAndFeel.installBorder(splitPane, "SplitPane.border"); 312 LookAndFeel.installColors(splitPane, "SplitPane.background", 313 "SplitPane.foreground"); 314 LookAndFeel.installProperty(splitPane, "opaque", Boolean.TRUE); 315 316 if (divider == null) divider = createDefaultDivider(); 317 divider.setBasicSplitPaneUI(this); 318 319 Border b = divider.getBorder(); 320 321 if (b == null || !(b instanceof UIResource )) { 322 divider.setBorder(UIManager.getBorder("SplitPaneDivider.border")); 323 } 324 325 dividerDraggingColor = UIManager.getColor("SplitPaneDivider.draggingColor"); 326 327 setOrientation(splitPane.getOrientation()); 328 329 LookAndFeel.installProperty(splitPane, "dividerSize", 333 UIManager.get("SplitPane.dividerSize")); 334 335 divider.setDividerSize(splitPane.getDividerSize()); 336 dividerSize = divider.getDividerSize(); 337 splitPane.add(divider, JSplitPane.DIVIDER); 338 339 setContinuousLayout(splitPane.isContinuousLayout()); 340 341 resetLayoutManager(); 342 343 345 if(nonContinuousLayoutDivider == null) { 346 setNonContinuousLayoutDivider( 347 createDefaultNonContinuousLayoutDivider(), 348 true); 349 } else { 350 setNonContinuousLayoutDivider(nonContinuousLayoutDivider, true); 351 } 352 353 if (managingFocusForwardTraversalKeys==null) { 355 managingFocusForwardTraversalKeys = new TreeSet(); 356 managingFocusForwardTraversalKeys.add( 357 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); 358 } 359 splitPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 360 managingFocusForwardTraversalKeys); 361 if (managingFocusBackwardTraversalKeys==null) { 363 managingFocusBackwardTraversalKeys = new TreeSet(); 364 managingFocusBackwardTraversalKeys.add( 365 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK)); 366 } 367 splitPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, 368 managingFocusBackwardTraversalKeys); 369 } 370 371 372 375 protected void installListeners() { 376 if ((propertyChangeListener = createPropertyChangeListener()) != 377 null) { 378 splitPane.addPropertyChangeListener(propertyChangeListener); 379 } 380 381 if ((focusListener = createFocusListener()) != null) { 382 splitPane.addFocusListener(focusListener); 383 } 384 } 385 386 387 390 protected void installKeyboardActions() { 391 InputMap km = getInputMap(JComponent. 392 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 393 394 SwingUtilities.replaceUIInputMap(splitPane, JComponent. 395 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, 396 km); 397 LazyActionMap.installLazyActionMap(splitPane, BasicSplitPaneUI .class, 398 "SplitPane.actionMap"); 399 } 400 401 InputMap getInputMap(int condition) { 402 if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) { 403 return (InputMap)DefaultLookup.get(splitPane, this, 404 "SplitPane.ancestorInputMap"); 405 } 406 return null; 407 } 408 409 412 public void uninstallUI(JComponent c) { 413 uninstallKeyboardActions(); 414 uninstallListeners(); 415 uninstallDefaults(); 416 dividerLocationIsSet = false; 417 dividerKeyboardResize = false; 418 splitPane = null; 419 } 420 421 422 425 protected void uninstallDefaults() { 426 if(splitPane.getLayout() == layoutManager) { 427 splitPane.setLayout(null); 428 } 429 430 if(nonContinuousLayoutDivider != null) { 431 splitPane.remove(nonContinuousLayoutDivider); 432 } 433 434 LookAndFeel.uninstallBorder(splitPane); 435 436 Border b = divider.getBorder(); 437 438 if (b instanceof UIResource ) { 439 divider.setBorder(null); 440 } 441 442 splitPane.remove(divider); 443 divider.setBasicSplitPaneUI(null); 444 layoutManager = null; 445 divider = null; 446 nonContinuousLayoutDivider = null; 447 448 setNonContinuousLayoutDivider(null); 449 450 splitPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); 453 splitPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); 454 } 455 456 457 460 protected void uninstallListeners() { 461 if (propertyChangeListener != null) { 462 splitPane.removePropertyChangeListener(propertyChangeListener); 463 propertyChangeListener = null; 464 } 465 if (focusListener != null) { 466 splitPane.removeFocusListener(focusListener); 467 focusListener = null; 468 } 469 470 keyboardUpLeftListener = null; 471 keyboardDownRightListener = null; 472 keyboardHomeListener = null; 473 keyboardEndListener = null; 474 keyboardResizeToggleListener = null; 475 handler = null; 476 } 477 478 479 482 protected void uninstallKeyboardActions() { 483 SwingUtilities.replaceUIActionMap(splitPane, null); 484 SwingUtilities.replaceUIInputMap(splitPane, JComponent. 485 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, 486 null); 487 } 488 489 490 493 protected PropertyChangeListener createPropertyChangeListener() { 494 return getHandler(); 495 } 496 497 private Handler getHandler() { 498 if (handler == null) { 499 handler = new Handler(); 500 } 501 return handler; 502 } 503 504 505 508 protected FocusListener createFocusListener() { 509 return getHandler(); 510 } 511 512 513 526 @Deprecated  527 protected ActionListener createKeyboardUpLeftListener() { 528 return new KeyboardUpLeftHandler(); 529 } 530 531 532 545 @Deprecated  546 protected ActionListener createKeyboardDownRightListener() { 547 return new KeyboardDownRightHandler(); 548 } 549 550 551 564 @Deprecated  565 protected ActionListener createKeyboardHomeListener() { 566 return new KeyboardHomeHandler(); 567 } 568 569 570 583 @Deprecated  584 protected ActionListener createKeyboardEndListener() { 585 return new KeyboardEndHandler(); 586 } 587 588 589 602 @Deprecated  603 protected ActionListener createKeyboardResizeToggleListener() { 604 return new KeyboardResizeToggleHandler(); 605 } 606 607 608 611 public int getOrientation() { 612 return orientation; 613 } 614 615 616 619 public void setOrientation(int orientation) { 620 this.orientation = orientation; 621 } 622 623 624 627 public boolean isContinuousLayout() { 628 return continuousLayout; 629 } 630 631 632 635 public void setContinuousLayout(boolean b) { 636 continuousLayout = b; 637 } 638 639 640 643 public int getLastDragLocation() { 644 return lastDragLocation; 645 } 646 647 648 651 public void setLastDragLocation(int l) { 652 lastDragLocation = l; 653 } 654 655 658 int getKeyboardMoveIncrement() { 659 return KEYBOARD_DIVIDER_MOVE_OFFSET; 660 } 661 662 669 public class PropertyHandler implements PropertyChangeListener 670 { 671 676 681 public void propertyChange(PropertyChangeEvent e) { 682 getHandler().propertyChange(e); 683 } 684 } 685 686 687 693 public class FocusHandler extends FocusAdapter 694 { 695 public void focusGained(FocusEvent ev) { 700 getHandler().focusGained(ev); 701 } 702 703 public void focusLost(FocusEvent ev) { 704 getHandler().focusLost(ev); 705 } 706 } 707 708 709 716 public class KeyboardUpLeftHandler implements ActionListener 717 { 718 public void actionPerformed(ActionEvent ev) { 719 if (dividerKeyboardResize) { 720 splitPane.setDividerLocation(Math.max(0,getDividerLocation 721 (splitPane) - getKeyboardMoveIncrement())); 722 } 723 } 724 } 725 726 733 public class KeyboardDownRightHandler implements ActionListener 734 { 735 public void actionPerformed(ActionEvent ev) { 736 if (dividerKeyboardResize) { 737 splitPane.setDividerLocation(getDividerLocation(splitPane) + 738 getKeyboardMoveIncrement()); 739 } 740 } 741 } 742 743 744 751 public class KeyboardHomeHandler implements ActionListener 752 { 753 public void actionPerformed(ActionEvent ev) { 754 if (dividerKeyboardResize) { 755 splitPane.setDividerLocation(0); 756 } 757 } 758 } 759 760 761 768 public class KeyboardEndHandler implements ActionListener 769 { 770 public void actionPerformed(ActionEvent ev) { 771 if (dividerKeyboardResize) { 772 Insets insets = splitPane.getInsets(); 773 int bottomI = (insets != null) ? insets.bottom : 0; 774 int rightI = (insets != null) ? insets.right : 0; 775 776 if (orientation == JSplitPane.VERTICAL_SPLIT) { 777 splitPane.setDividerLocation(splitPane.getHeight() - 778 bottomI); 779 } 780 else { 781 splitPane.setDividerLocation(splitPane.getWidth() - 782 rightI); 783 } 784 } 785 } 786 } 787 788 789 796 public class KeyboardResizeToggleHandler implements ActionListener 797 { 798 public void actionPerformed(ActionEvent ev) { 799 if (!dividerKeyboardResize) { 800 splitPane.requestFocus(); 801 } 802 } 803 } 804 805 808 public BasicSplitPaneDivider getDivider() { 809 return divider; 810 } 811 812 813 817 protected Component createDefaultNonContinuousLayoutDivider() { 818 return new Canvas() { 819 public void paint(Graphics g) { 820 if(!isContinuousLayout() && getLastDragLocation() != -1) { 821 Dimension size = splitPane.getSize(); 822 823 g.setColor(dividerDraggingColor); 824 if(orientation == JSplitPane.HORIZONTAL_SPLIT) { 825 g.fillRect(0, 0, dividerSize - 1, size.height - 1); 826 } else { 827 g.fillRect(0, 0, size.width - 1, dividerSize - 1); 828 } 829 } 830 } 831 }; 832 } 833 834 835 841 protected void setNonContinuousLayoutDivider(Component newDivider) { 842 setNonContinuousLayoutDivider(newDivider, true); 843 } 844 845 846 849 protected void setNonContinuousLayoutDivider(Component newDivider, 850 boolean rememberSizes) { 851 rememberPaneSizes = rememberSizes; 852 if(nonContinuousLayoutDivider != null && splitPane != null) { 853 splitPane.remove(nonContinuousLayoutDivider); 854 } 855 nonContinuousLayoutDivider = newDivider; 856 } 857 858 private void addHeavyweightDivider() { 859 if(nonContinuousLayoutDivider != null && splitPane != null) { 860 861 862 Component leftC = splitPane.getLeftComponent(); 866 Component rightC = splitPane.getRightComponent(); 867 int lastLocation = splitPane. 868 getDividerLocation(); 869 870 if(leftC != null) 871 splitPane.setLeftComponent(null); 872 if(rightC != null) 873 splitPane.setRightComponent(null); 874 splitPane.remove(divider); 875 splitPane.add(nonContinuousLayoutDivider, BasicSplitPaneUI. 876 NON_CONTINUOUS_DIVIDER, 877 splitPane.getComponentCount()); 878 splitPane.setLeftComponent(leftC); 879 splitPane.setRightComponent(rightC); 880 splitPane.add(divider, JSplitPane.DIVIDER); 881 if(rememberPaneSizes) { 882 splitPane.setDividerLocation(lastLocation); 883 } 884 } 885 886 } 887 888 889 894 public Component getNonContinuousLayoutDivider() { 895 return nonContinuousLayoutDivider; 896 } 897 898 899 903 public JSplitPane getSplitPane() { 904 return splitPane; 905 } 906 907 908 911 public BasicSplitPaneDivider createDefaultDivider() { 912 return new BasicSplitPaneDivider (this); 913 } 914 915 916 919 public void resetToPreferredSizes(JSplitPane jc) { 920 if(splitPane != null) { 921 layoutManager.resetToPreferredSizes(); 922 splitPane.revalidate(); 923 splitPane.repaint(); 924 } 925 } 926 927 928 931 public void setDividerLocation(JSplitPane jc, int location) { 932 if (!ignoreDividerLocationChange) { 933 dividerLocationIsSet = true; 934 splitPane.revalidate(); 935 splitPane.repaint(); 936 937 if (keepHidden) { 938 Insets insets = splitPane.getInsets(); 939 int orientation = splitPane.getOrientation(); 940 if ((orientation == JSplitPane.VERTICAL_SPLIT && 941 location != insets.top && 942 location != splitPane.getHeight()-divider.getHeight()-insets.top) || 943 (orientation == JSplitPane.HORIZONTAL_SPLIT && 944 location != insets.left && 945 location != splitPane.getWidth()-divider.getWidth()-insets.left)) { 946 setKeepHidden(false); 947 } 948 } 949 } 950 else { 951 ignoreDividerLocationChange = false; 952 } 953 } 954 955 956 960 public int getDividerLocation(JSplitPane jc) { 961 if(orientation == JSplitPane.HORIZONTAL_SPLIT) 962 return divider.getLocation().x; 963 return divider.getLocation().y; 964 } 965 966 967 970 public int getMinimumDividerLocation(JSplitPane jc) { 971 int minLoc = 0; 972 Component leftC = splitPane.getLeftComponent(); 973 974 if ((leftC != null) && (leftC.isVisible())) { 975 Insets insets = splitPane.getInsets(); 976 Dimension minSize = leftC.getMinimumSize(); 977 if(orientation == JSplitPane.HORIZONTAL_SPLIT) { 978 minLoc = minSize.width; 979 } else { 980 minLoc = minSize.height; 981 } 982 if(insets != null) { 983 if(orientation == JSplitPane.HORIZONTAL_SPLIT) { 984 minLoc += insets.left; 985 } else { 986 minLoc += insets.top; 987 } 988 } 989 } 990 return minLoc; 991 } 992 993 994 997 public int getMaximumDividerLocation(JSplitPane jc) { 998 Dimension splitPaneSize = splitPane.getSize(); 999 int maxLoc = 0; 1000 Component rightC = splitPane.getRightComponent(); 1001 1002 if (rightC != null) { 1003 Insets insets = splitPane.getInsets(); 1004 Dimension minSize = new Dimension(0, 0); 1005 if (rightC.isVisible()) { 1006 minSize = rightC.getMinimumSize(); 1007 } 1008 if(orientation == JSplitPane.HORIZONTAL_SPLIT) { 1009 maxLoc = splitPaneSize.width - minSize.width; 1010 } else { 1011 maxLoc = splitPaneSize.height - minSize.height; 1012 } 1013 maxLoc -= dividerSize; 1014 if(insets != null) { 1015 if(orientation == JSplitPane.HORIZONTAL_SPLIT) { 1016 maxLoc -= insets.right; 1017 } else { 1018 maxLoc -= insets.top; 1019 } 1020 } 1021 } 1022 return Math.max(getMinimumDividerLocation(splitPane), maxLoc); 1023 } 1024
|