1 19 20 package org.netbeans.swing.tabcontrol.plaf; 21 22 import java.awt.AlphaComposite ; 23 import java.awt.BorderLayout ; 24 import java.awt.Component ; 25 import java.awt.Composite ; 26 import java.awt.Container ; 27 import java.awt.Dimension ; 28 import java.awt.Graphics ; 29 import java.awt.Graphics2D ; 30 import java.awt.GraphicsEnvironment ; 31 import java.awt.Image ; 32 import java.awt.Insets ; 33 import java.awt.LayoutManager ; 34 import java.awt.Point ; 35 import java.awt.Polygon ; 36 import java.awt.Rectangle ; 37 import java.awt.event.ActionEvent ; 38 import java.awt.event.ActionListener ; 39 import java.awt.event.ComponentAdapter ; 40 import java.awt.event.ComponentEvent ; 41 import java.awt.event.ComponentListener ; 42 import java.awt.event.HierarchyEvent ; 43 import java.awt.event.HierarchyListener ; 44 import java.awt.event.MouseEvent ; 45 import java.awt.event.MouseListener ; 46 import java.awt.geom.AffineTransform ; 47 import java.awt.image.BufferedImage ; 48 import java.beans.PropertyChangeEvent ; 49 import java.beans.PropertyChangeListener ; 50 import java.util.HashSet ; 51 import java.util.Iterator ; 52 import java.util.List ; 53 import java.util.Set ; 54 import javax.swing.JComponent ; 55 import javax.swing.JPanel ; 56 import javax.swing.SingleSelectionModel ; 57 import javax.swing.SwingUtilities ; 58 import javax.swing.Timer ; 59 import javax.swing.UIManager ; 60 import javax.swing.border.Border ; 61 import javax.swing.event.ChangeEvent ; 62 import javax.swing.event.ChangeListener ; 63 import javax.swing.event.ListDataEvent ; 64 import javax.swing.plaf.ComponentUI ; 65 import org.netbeans.swing.tabcontrol.TabData; 66 import org.netbeans.swing.tabcontrol.TabDisplayer; 67 import org.netbeans.swing.tabcontrol.TabbedContainer; 68 import org.netbeans.swing.tabcontrol.TabbedContainerUI; 69 import org.netbeans.swing.tabcontrol.WinsysInfoForTabbed; 70 import org.netbeans.swing.tabcontrol.event.ArrayDiff; 71 import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent; 72 import org.netbeans.swing.tabcontrol.event.ComplexListDataListener; 73 import org.netbeans.swing.tabcontrol.event.TabActionEvent; 74 import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent; 75 76 87 public class DefaultTabbedContainerUI extends TabbedContainerUI { 88 92 private ActionListener actionListener = null; 93 97 98 public static final String KEY_EDITOR_CONTENT_BORDER = "TabbedContainer.editor.contentBorder"; 100 public static final String KEY_EDITOR_TABS_BORDER = "TabbedContainer.editor.tabsBorder"; 102 public static final String KEY_EDITOR_OUTER_BORDER = "TabbedContainer.editor.outerBorder"; 104 105 public static final String KEY_VIEW_CONTENT_BORDER = "TabbedContainer.view.contentBorder"; 107 public static final String KEY_VIEW_TABS_BORDER = "TabbedContainer.view.tabsBorder"; 109 public static final String KEY_VIEW_OUTER_BORDER = "TabbedContainer.view.outerBorder"; 111 112 public static final String KEY_SLIDING_CONTENT_BORDER = "TabbedContainer.sliding.contentBorder"; 114 public static final String KEY_SLIDING_TABS_BORDER = "TabbedContainer.sliding.tabsBorder"; 116 public static final String KEY_SLIDING_OUTER_BORDER = "TabbedContainer.sliding.outerBorder"; 118 119 public static final String KEY_TOOLBAR_CONTENT_BORDER = "TabbedContainer.toolbar.contentBorder"; 121 public static final String KEY_TOOLBAR_TABS_BORDER = "TabbedContainer.toolbar.tabsBorder"; 123 public static final String KEY_TOOLBAR_OUTER_BORDER = "TabbedContainer.toolbar.outerBorder"; 125 129 protected ComponentListener componentListener = null; 130 135 protected ChangeListener selectionListener = null; 136 142 protected ComplexListDataListener modelListener = null; 143 148 protected LayoutManager contentDisplayerLayout = null; 149 154 protected PropertyChangeListener propertyChangeListener = null; 155 161 protected FxProvider slideEffectManager = null; 162 163 168 protected JComponent contentDisplayer = null; 169 175 protected TabDisplayer tabDisplayer = null; 176 177 private HierarchyListener hierarchyListener = null; 178 179 182 public DefaultTabbedContainerUI(TabbedContainer c) { 183 super(c); 184 } 185 186 public static ComponentUI createUI(JComponent c) { 187 return new DefaultTabbedContainerUI((TabbedContainer) c); 188 } 189 190 195 public final void installUI(JComponent c) { 196 assert c == container; 197 container.setLayout(createLayout()); 198 contentDisplayer = createContentDisplayer(); 199 tabDisplayer = createTabDisplayer(); 200 selectionListener = createSelectionListener(); 201 modelListener = createModelListener(); 202 componentListener = createComponentListener(); 203 propertyChangeListener = createPropertyChangeListener(); 204 contentDisplayerLayout = createContentDisplayerLayout(); 205 slideEffectManager = createFxProvider(); 206 actionListener = createDisplayerActionListener(); 207 container.setLayout(createLayout()); 208 hierarchyListener = new ContainerHierarchyListener(); 209 forward = new ForwardingMouseListener(container); 210 installContentDisplayer(); 211 installTabDisplayer(); 212 installBorders(); 213 installListeners(); 214 install(); 215 tabDisplayer.getSelectionModel().addChangeListener(selectionListener); 218 219 } 220 221 222 223 TabDisplayer getTabDisplayer() { 224 return tabDisplayer; 225 } 226 227 private MouseListener forward = null; 228 229 234 public final void uninstallUI(JComponent c) { 235 assert c == container; 236 tabDisplayer.getSelectionModel().removeChangeListener(selectionListener); 237 uninstall(); 238 uninstallListeners(); 239 uninstallDisplayers(); 240 241 container = null; 242 contentDisplayer = null; 243 tabDisplayer = null; 244 selectionListener = null; 245 modelListener = null; 246 componentListener = null; 247 propertyChangeListener = null; 248 contentDisplayerLayout = null; 249 actionListener = null; 250 forward = null; 251 } 252 253 257 protected void install() { 258 259 } 260 261 264 protected void uninstall() { 265 266 } 267 268 protected boolean uichange() { 269 installBorders(); 270 return false; 271 } 272 273 276 protected void installContentDisplayer() { 277 contentDisplayer.setLayout(contentDisplayerLayout); 278 container.add(contentDisplayer, BorderLayout.CENTER); 279 } 280 281 285 protected void installTabDisplayer() { 286 container.add(tabDisplayer, BorderLayout.NORTH); 287 tabDisplayer.registerShortcuts(container); 288 } 289 290 293 protected void installBorders() { 294 String tabsKey; 295 String contentKey; 296 String outerKey; 297 switch (container.getType()) { 298 case TabbedContainer.TYPE_EDITOR : 299 tabsKey = KEY_EDITOR_TABS_BORDER; 300 contentKey = KEY_EDITOR_CONTENT_BORDER; 301 outerKey = KEY_EDITOR_OUTER_BORDER; 302 break; 303 case TabbedContainer.TYPE_VIEW : 304 tabsKey = KEY_VIEW_TABS_BORDER; 305 contentKey = KEY_VIEW_CONTENT_BORDER; 306 outerKey = KEY_VIEW_OUTER_BORDER; 307 break; 308 case TabbedContainer.TYPE_SLIDING : 309 tabsKey = KEY_SLIDING_TABS_BORDER; 310 contentKey = KEY_SLIDING_CONTENT_BORDER; 311 outerKey = KEY_SLIDING_OUTER_BORDER; 312 break; 313 case TabbedContainer.TYPE_TOOLBAR : 314 tabsKey = KEY_TOOLBAR_TABS_BORDER; 315 contentKey = KEY_TOOLBAR_CONTENT_BORDER; 316 outerKey = KEY_TOOLBAR_OUTER_BORDER; 317 break; 318 default : 319 throw new IllegalStateException ("Unknown type: " 320 + container.getType()); 321 } 322 try { 323 Border b = (Border ) UIManager.get (contentKey); 324 contentDisplayer.setBorder(b); 325 b = (Border ) UIManager.get (tabsKey); 326 tabDisplayer.setBorder(b); 327 b = (Border ) UIManager.get (outerKey); 328 container.setBorder(b); 329 } catch (ClassCastException cce) { 330 System.err.println ("Expected a border from UIManager for " 331 + tabsKey + "," + contentKey + "," + outerKey); 332 } 333 } 334 335 340 protected void installListeners() { 341 container.addComponentListener(componentListener); 342 container.addHierarchyListener (hierarchyListener); 343 tabDisplayer.addMouseListener (forward); 346 contentDisplayer.addMouseListener (forward); 347 } 348 349 356 protected void attachModelAndSelectionListeners() { 357 container.getModel().addComplexListDataListener(modelListener); 358 container.addPropertyChangeListener(propertyChangeListener); 359 tabDisplayer.setActive (container.isActive()); 360 tabDisplayer.addActionListener (actionListener); 361 } 362 363 371 protected void detachModelAndSelectionListeners() { 372 container.getModel().removeComplexListDataListener(modelListener); 373 container.removePropertyChangeListener(propertyChangeListener); 374 tabDisplayer.removeActionListener (actionListener); 375 } 376 377 380 protected void uninstallListeners() { 381 container.removeComponentListener(componentListener); 382 container.removeHierarchyListener (hierarchyListener); 383 componentListener = null; 384 propertyChangeListener = null; 385 tabDisplayer.removeMouseListener (forward); 386 contentDisplayer.removeMouseListener (forward); 387 } 388 389 394 protected void uninstallDisplayers() { 395 container.remove(contentDisplayer); 396 container.remove(tabDisplayer); 397 tabDisplayer.unregisterShortcuts(container); 398 contentDisplayer.removeAll(); 399 contentDisplayer = null; 400 tabDisplayer = null; 401 } 402 403 406 protected TabDisplayer createTabDisplayer() { 407 TabDisplayer result = null; 408 WinsysInfoForTabbed winsysInfo = container.getWinsysInfo(); 409 if (winsysInfo != null) { 410 result = new TabDisplayer( 411 container.getModel(), container.getType(), winsysInfo); 412 } else { 413 result = new TabDisplayer( 414 container.getModel(), container.getType(), container.getLocationInformer()); 415 } 416 result.setName("Tab Displayer"); return result; 418 } 419 420 425 protected JPanel createContentDisplayer() { 426 JPanel result = new JPanel (); 427 result.setName ("Content displayer"); return result; 429 } 430 431 437 protected FxProvider createFxProvider() { 438 if (NO_EFFECTS || (tabDisplayer.getType() != TabDisplayer.TYPE_SLIDING && !EFFECTS_EVERYWHERE)) { 439 return new NoOpFxProvider(); 440 } else { 441 if (ADD_TO_GLASSPANE) { 442 return new LiveComponentSlideFxProvider(); 443 } else { 444 return new ImageSlideFxProvider(); 445 } 446 } 447 } 448 449 454 protected LayoutManager createContentDisplayerLayout() { 455 return new StackLayout(); 456 } 457 458 469 protected LayoutManager createLayout() { 470 if (container.getType() == TabbedContainer.TYPE_SLIDING) { 471 return new SlidingTabsLayout(); 472 } else if (container.getType() == TabbedContainer.TYPE_TOOLBAR) { 473 return new ToolbarTabsLayout(); 474 } else { 475 return new BorderLayout (); 476 } 477 } 478 479 483 protected ComponentListener createComponentListener() { 484 return new ContainerComponentListener(); 485 } 486 487 493 protected PropertyChangeListener createPropertyChangeListener() { 494 return new ContainerPropertyChangeListener(); 495 } 496 497 502 private ActionListener createDisplayerActionListener() { 503 return new DisplayerActionListener(); 504 } 505 506 510 protected void ensureSelectedComponentIsShowing() { 511 int i = tabDisplayer.getSelectionModel().getSelectedIndex(); 512 if (i != -1) { 513 TabData td = container.getModel().getTab(i); 514 showComponent(toComp(td)); 515 } 516 } 517 518 520 protected final Component toComp (TabData data) { 521 return container.getComponentConverter().getComponent(data); 522 } 523 524 538 protected Component showComponent(Component c) { 539 if (contentDisplayerLayout instanceof StackLayout) { 540 StackLayout stack = ((StackLayout) contentDisplayerLayout); 541 Component last = stack.getVisibleComponent(); 542 stack.showComponent(c, contentDisplayer); 543 if (c != null) { 544 Integer offset = (Integer )((JComponent )c).getClientProperty("MultiViewBorderHack.topOffset"); 545 contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", offset); 546 } else { 547 contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", null); 548 } 549 if (last != c) { 550 maybeRemoveLastComponent(last); 551 return last; 552 } 553 } 554 return null; 555 } 556 557 566 protected final void showComponentWithFxProvider (Component c) { 567 if (slideEffectManager == null || !container.isShowing() || (!(c instanceof JComponent ))) { 568 Component last = showComponent (c); 569 maybeRemoveLastComponent (last); 570 } else { 571 slideEffectManager.start((JComponent ) c, container.getRootPane(), 572 tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION)); 573 } 574 } 575 576 582 private final void maybeRemoveLastComponent (Component c) { 583 if (c != null && container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ONLY_SELECTED) { 584 contentDisplayer.remove (c); 585 } 586 } 587 588 591 protected void initDisplayer() { 592 if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { 593 List tabs = container.getModel().getTabs(); 594 Component curC = null; 595 for (Iterator iter = tabs.iterator(); iter.hasNext();) { 596 curC = toComp ((TabData) iter.next()); 597 contentDisplayer.add(curC, ""); 599 } 600 } else { 601 int i = tabDisplayer.getSelectionModel().getSelectedIndex(); 602 if (i != -1) { 603 TabData td = container.getModel().getTab(i); 604 contentDisplayer.add(toComp(td), ""); 605 } 606 } 607 updateActiveState(); 608 } 609 610 625 protected ComplexListDataListener createModelListener() { 626 return new ModelListener(); 627 } 628 629 634 protected ChangeListener createSelectionListener() { 635 return new SelectionListener(); 636 } 637 638 639 private void updateActiveState() { 640 TabDisplayer displ = tabDisplayer; 645 TabbedContainer cont = container; 646 if (displ != null && cont != null) { 647 displ.setActive(cont.isActive()); 648 } 649 650 } 651 652 public Rectangle getTabRect(int tab, Rectangle r) { 653 if (r == null) { 654 r = new Rectangle (); 655 } 656 tabDisplayer.getTabRect(tab, r); 657 Point p = tabDisplayer.getLocation(); 658 r.x += p.x; 659 r.y += p.y; 660 return r; 661 } 662 663 protected void requestAttention (int tab) { 664 tabDisplayer.requestAttention (tab); 665 } 666 667 protected void cancelRequestAttention (int tab) { 668 tabDisplayer.cancelRequestAttention(tab); 669 } 670 671 public void setShowCloseButton (boolean val) { 672 tabDisplayer.setShowCloseButton(val); 673 } 674 675 public boolean isShowCloseButton () { 676 return tabDisplayer.isShowCloseButton(); 677 } 678 679 683 private static final class DefaultWindowBorder implements Border { 684 private static final Insets insets = new Insets (1, 1, 2, 2); 685 686 public void paintBorder(Component c, Graphics g, int x, int y, int w, 687 int h) { 688 g.translate(x, y); 689 690 g.setColor(UIManager.getColor("controlShadow")); g.drawRect(0, 0, w - 2, h - 2); 692 g.setColor(UIManager.getColor("controlHighlight")); g.drawLine(w - 1, 1, w - 1, h - 1); 694 g.drawLine(1, h - 1, w - 1, h - 1); 695 696 g.translate(-x, -y); 697 } 698 699 public Insets getBorderInsets(Component c) { 700 return insets; 701 } 702 703 public boolean isBorderOpaque() { 704 return true; 705 } 706 } 708 protected class ContainerPropertyChangeListener implements PropertyChangeListener { 709 710 public void propertyChange(PropertyChangeEvent evt) { 711 if (TabbedContainer.PROP_ACTIVE.equals(evt.getPropertyName())) { 712 updateActiveState(); 713 } 714 } 715 } 716 717 722 protected final void updateOrientation() { 723 if (!container.isDisplayable()) { 724 return; 725 } 726 if (Boolean.FALSE.equals(container.getClientProperty (TabbedContainer.PROP_MANAGE_TAB_POSITION))) { 727 return; 730 } 731 Object currOrientation = tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION); 732 Container window = container.getTopLevelAncestor(); 733 734 Rectangle containerBounds = container.getBounds(); 735 containerBounds = SwingUtilities.convertRectangle(container, containerBounds, window); 736 737 boolean longestIsVertical = containerBounds.width < containerBounds.height; 738 739 int distanceToLeft = containerBounds.x; 740 int distanceToTop = containerBounds.y; 741 int distanceToRight = window.getWidth() - (containerBounds.x + containerBounds.width); 742 int distanceToBottom = window.getHeight() - (containerBounds.y + containerBounds.height); 743 744 Object orientation; 745 if (!longestIsVertical) { 746 if (distanceToBottom > distanceToTop) { 747 orientation = TabDisplayer.ORIENTATION_NORTH; 748 } else { 749 orientation = TabDisplayer.ORIENTATION_SOUTH; 750 } 751 } else { 752 if (distanceToLeft > distanceToRight) { 753 orientation = TabDisplayer.ORIENTATION_EAST; 754 } else { 755 orientation = TabDisplayer.ORIENTATION_WEST; 756 } 757 } 758 759 if (currOrientation != orientation) { 760 tabDisplayer.putClientProperty( 761 TabDisplayer.PROP_ORIENTATION, orientation); 762 container.validate(); 763 } 764 } 765 766 public int tabForCoordinate(Point p) { 767 p = SwingUtilities.convertPoint(container, p, tabDisplayer); 768 return tabDisplayer.tabForCoordinate(p); 769 } 770 771 public void makeTabVisible(int tab) { 772 tabDisplayer.makeTabVisible (tab); 773 } 774 775 public SingleSelectionModel getSelectionModel() { 776 return tabDisplayer.getSelectionModel(); 777 } 778 779 public Image createImageOfTab(int idx) { 780 return tabDisplayer.getUI().createImageOfTab(idx); 781 } 782 783 public Polygon getExactTabIndication(int idx) { 784 Polygon result = tabDisplayer.getUI().getExactTabIndication(idx); 785 scratchPoint.setLocation(0,0); 786 Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container); 787 result.translate (-p.x, -p.y); 788 return appendContentBoundsTo(result); 789 } 790 791 private Point scratchPoint = new Point (); 792 public Polygon getInsertTabIndication(int idx) { 793 Polygon result = tabDisplayer.getUI().getInsertTabIndication(idx); 794 scratchPoint.setLocation(0,0); 795 Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container); 796 result.translate (-p.x, -p.y); 797 return appendContentBoundsTo(result); 798 } 799 800 private Polygon appendContentBoundsTo (Polygon p) { 801 int width = contentDisplayer.getWidth(); 802 int height = contentDisplayer.getHeight(); 803 804 int[] xpoints = new int[p.npoints + 4]; 805 int[] ypoints = new int[xpoints.length]; 806 807 809 int pos = 0; 810 Object orientation = tabDisplayer.getClientProperty (TabDisplayer.PROP_ORIENTATION); 811 812 int tabsHeight = tabDisplayer.getHeight(); 813 if (orientation == null || orientation == TabDisplayer.ORIENTATION_NORTH) { 814 815 xpoints[pos] = 0; 816 ypoints[pos] = tabsHeight; 817 818 pos++; 819 820 xpoints[pos] = p.xpoints[p.npoints-1]; 821 ypoints[pos] = tabsHeight; 822 pos++; 823 824 for (int i=0; i < p.npoints-2; i++) { 825 xpoints [pos] = p.xpoints[i]; 826 ypoints [pos] = p.ypoints[i]; 827 pos++; 828 } 829 830 xpoints[pos] = xpoints[pos-1]; 831 ypoints[pos] = tabsHeight; 832 833 pos++; 834 835 xpoints[pos] = width - 1; 836 ypoints[pos] = tabsHeight; 837 838 pos++; 839 840 xpoints[pos] = width - 1; 841 ypoints[pos] = height -1; 842 843 pos++; 844 845 xpoints[pos] = 0; 846 ypoints[pos] = height - 1; 847 } else if (orientation == TabDisplayer.ORIENTATION_SOUTH) { 848 int yxlate = contentDisplayer.getHeight() * 2; 849 850 xpoints[pos] = 0; 851 ypoints[pos] = 0; 852 853 pos++; 854 855 xpoints[pos] = container.getWidth(); 856 ypoints[pos] = 0; 857 858 pos++; 859 860 xpoints[pos] = container.getWidth(); 861 ypoints[pos] = container.getHeight() - tabsHeight; 862 863 pos++; 864 865 int upperRight = 0; 866 int highestFound = Integer.MIN_VALUE; 869 for (int i = p.npoints-2; i >= 0; i--) { 870 if (highestFound < p.ypoints[i]) { 871 upperRight = i; 872 highestFound = p.ypoints[i]; 873 } else if (highestFound == p.ypoints[i]) { 874 break; 875 } 876 } 877 878 int curr = upperRight-1; 879 for (int i=p.npoints-1; i >= 0; i--) { 880 xpoints[pos] = p.xpoints[curr]; 881 if (ypoints[pos] == highestFound) { 882 ypoints[pos] = Math.min (tabDisplayer.getLocation().y, p.ypoints[curr] + yxlate); 883 } else { 884 ypoints[pos] = p.ypoints[curr] + yxlate; 885 } 886 pos++; 887 curr++; 888 if (curr == p.npoints-1) { 889 curr = 0; 890 } 891 } 892 893 xpoints[pos] = 0; 894 ypoints[pos] = container.getHeight() - tabsHeight; 895 } else { 896 xpoints = p.xpoints; 898 ypoints = p.ypoints; 899 } 900 901 Polygon result = new EqualPolygon (xpoints, ypoints, xpoints.length); 902 return result; 903 } 904 905 public Rectangle getContentArea() { 906 return contentDisplayer.getBounds(); 907 } 908 909 public Rectangle getTabsArea() { 910 return tabDisplayer.getBounds(); 911 } 912 913 public int dropIndexOfPoint(Point p) { 914 Point p2 = SwingUtilities.convertPoint(container, p, tabDisplayer); 915 return tabDisplayer.getUI().dropIndexOfPoint (p2); 916 } 917 918 public Rectangle getTabsArea(Rectangle dest) { 919 return tabDisplayer.getBounds(); 920 } 921 922 926 protected class ContainerComponentListener extends ComponentAdapter { 927 public ContainerComponentListener() { 928 } 929 930 public void componentMoved (ComponentEvent e) { 931 if (container.getType() == TabbedContainer.TYPE_SLIDING) { 932 updateOrientation(); 933 } 934 } 935 936 public void componentResized (ComponentEvent e) { 937 if (container.getType() == TabbedContainer.TYPE_SLIDING) { 938 updateOrientation(); 939 } 940 } 941 } 942 943 private boolean bug4924561knownShowing = false; 944 948 private class ContainerHierarchyListener implements HierarchyListener { 949 public ContainerHierarchyListener() { 950 } 951 952 public void hierarchyChanged(HierarchyEvent e) { 953 if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { 954 boolean showing = container.isShowing(); 955 if (showing != bug4924561knownShowing) { 956 if (container.isShowing()) { 957 initDisplayer(); 958 attachModelAndSelectionListeners(); 959 ensureSelectedComponentIsShowing(); 960 if (container.getType() == TabbedContainer.TYPE_SLIDING) { 961 updateOrientation(); 962 } 963 } else { 964 detachModelAndSelectionListeners(); 965 if (container.getType() == TabbedContainer.TYPE_SLIDING) { 966 updateOrientation(); 967 } 968 } 969 } 970 bug4924561knownShowing = showing; 971 } 972 } 973 } 974 975 private class ToolbarTabsLayout implements LayoutManager { 976 977 public void layoutContainer(Container container) { 978 Dimension tabSize = tabDisplayer.getPreferredSize(); 979 Insets ins = container.getInsets(); 980 int w = container.getWidth() - (ins.left + ins.right); 981 tabDisplayer.setBounds (ins.left, ins.top, 982 w, 983 tabSize.height); 984 contentDisplayer.setBounds(ins.left, 985 ins.top + tabSize.height, w, 986 container.getHeight() - (ins.top + ins.bottom + tabSize.height)); 987 } 988 989 public Dimension minimumLayoutSize(Container container) { 990 Dimension tabSize = tabDisplayer.getMinimumSize(); 991 Dimension contentSize = contentDisplayer.getMinimumSize(); 992 Insets ins = container.getInsets(); 993 Dimension result = new Dimension (ins.left + ins.top, ins.right + ins.bottom); 994 result.width += Math.max (tabSize.width, contentSize.width); 995 result.height += tabSize.height + contentSize.height; 996 return result; 997 } 998 999 public Dimension preferredLayoutSize(Container container) { 1000 Dimension tabSize = tabDisplayer.getPreferredSize(); 1001 Dimension contentSize = contentDisplayer.getPreferredSize(); 1002 Insets ins = container.getInsets(); 1003 Dimension result = new Dimension (ins.left + ins.top, ins.right + ins.bottom); 1004 result.width += Math.max (tabSize.width, contentSize.width); 1005 result.height += tabSize.height + contentSize.height; 1006 return result; 1007 } 1008 1009 public void removeLayoutComponent(Component component) { 1010 } 1012 1013 public void addLayoutComponent(String str, Component component) { 1014 } 1016 } 1017 1018 1023 protected class SelectionListener implements ChangeListener { 1024 public SelectionListener() { 1025 } 1026 1027 public void stateChanged(ChangeEvent e) { 1028 if (container.isShowing()) { 1029 int idx = tabDisplayer.getSelectionModel().getSelectedIndex(); 1030 if (idx != -1) { 1031 Component c = toComp(container.getModel().getTab(idx)); 1032 c.setBounds(0, 0, contentDisplayer.getWidth(), 1033 contentDisplayer.getHeight()); 1034 showComponentWithFxProvider(c); 1035 } else { 1036 showComponent (null); 1037 } 1038 } 1039 } 1040 } 1041 1042 1046 protected class ModelListener implements ComplexListDataListener { 1047 public ModelListener() { 1048 } 1049 1050 1054 public void contentsChanged(ListDataEvent e) { 1055 if (e instanceof ComplexListDataEvent) { 1057 ComplexListDataEvent clde = (ComplexListDataEvent) e; 1058 int index = clde.getIndex0(); 1059 if (clde.isUserObjectChanged() && index != -1) { 1060 Component comp = contentDisplayer.getComponent( 1061 index); 1062 Component nue = toComp(tabDisplayer.getModel().getTab(index)); 1063 contentDisplayer.remove(comp); 1064 1065 boolean add = 1066 container.getContentPolicy() == 1067 TabbedContainer.CONTENT_POLICY_ADD_ALL || 1068 index == 1069 container.getSelectionModel().getSelectedIndex(); 1070 1071 if (add) { 1072 contentDisplayer.add(nue, index); 1073 } 1074 } 1075 if (clde.isTextChanged()) { 1076 maybeMakeSelectedTabVisible(clde); 1077 } 1078 } 1079 } 1080 1081 1088 private void maybeMakeSelectedTabVisible(ComplexListDataEvent clde) { 1089 if (!container.isShowing() || container.getWidth() < 10) { 1090 return; 1093 } 1094 if (tabDisplayer.getType() == TabDisplayer.TYPE_EDITOR) { 1095 int idx = tabDisplayer.getSelectionModel().getSelectedIndex(); 1096 if ((clde.getIndex0() == clde.getIndex1()) 1099 && clde.getIndex0() == idx) { 1100 (tabDisplayer).makeTabVisible(idx); 1101 } 1102 } 1103 } 1104 1105 1106 public void intervalAdded(ListDataEvent e) { 1107 if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { 1108 Component curC = null; 1109 for (int i = e.getIndex0(); i <= e.getIndex1(); i++) { 1110 curC = toComp(container.getModel().getTab(i)); 1111 contentDisplayer.add(curC, ""); 1112 } 1113 } 1114 } 1115 1116 public void intervalRemoved(ListDataEvent e) { 1117 ComplexListDataEvent clde = (ComplexListDataEvent) e; 1119 TabData[] removedTabs = clde.getAffectedItems(); 1120 Component curComp; 1121 for (int i = 0; i < removedTabs.length; i++) { 1122 curComp = toComp(removedTabs[i]); 1123 contentDisplayer.remove(curComp); 1124 } 1125 } 1126 1127 public void indicesAdded(ComplexListDataEvent e) { 1128 Component curC = null; 1129 if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { 1130 int[] indices = e.getIndices(); 1131 for (int i = 0; i < indices.length; i++) { 1132 curC = toComp(container.getModel().getTab(indices[i])); 1133 contentDisplayer.add(curC, ""); 1134 } 1135 } 1136 } 1137 1138 public void indicesRemoved(ComplexListDataEvent e) { 1139 int[] indices = e.getIndices(); 1140 TabData[] removedTabs = e.getAffectedItems(); 1141 Component curComp; 1142 for (int i = 0; i < indices.length; i++) { 1143 curComp = toComp(removedTabs[i]); 1144 contentDisplayer.remove(curComp); 1146 } 1147 } 1148 1149 public void indicesChanged(ComplexListDataEvent e) { 1150 if (e instanceof VeryComplexListDataEvent) { 1153 ArrayDiff dif = ((VeryComplexListDataEvent) e).getDiff(); 1154 1155 Set deleted = dif.getDeletedIndices(); 1157 Set added = dif.getAddedIndices(); 1158 1159 TabData[] old = dif.getOldData(); 1161 TabData[] nue = dif.getNewData(); 1163 1164 Set <Component > components = new HashSet <Component >(); 1170 if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { 1171 for (int i = 0; i < nue.length; i++) { 1172 components.add(toComp(nue[i])); 1173 } 1174 } 1175 boolean changed = false; 1176 1177 synchronized (contentDisplayer.getTreeLock()) { 1178 if (!deleted.isEmpty()) { 1180 Iterator i = deleted.iterator(); 1181 while (i.hasNext()) { 1182 Integer idx = (Integer ) i.next(); 1184 TabData del = old[idx.intValue()]; 1186 if (!components.contains(toComp(del))) { 1188 contentDisplayer.remove(toComp(del)); 1190 changed = true; 1191 } 1192 } 1193 } 1194 1195 if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { 1196 1197 if (!added.isEmpty()) { 1199 Iterator i = added.iterator(); 1200 while (i.hasNext()) { 1201 Integer idx = (Integer ) i.next(); 1203 TabData add = nue[idx.intValue()]; 1205 if (!contentDisplayer.isAncestorOf( 1208 toComp(add))) { 1209 contentDisplayer.add(toComp(add), ""); 1210 changed = true; 1211 } 1212 } 1213 } 1214 } 1215 } 1216 if (changed) { 1218 contentDisplayer.revalidate(); 1219 contentDisplayer.repaint(); 1220 } 1221 } 1222 } 1223 } 1224 1225 1229 private class DisplayerActionListener implements ActionListener { 1230 public void actionPerformed (ActionEvent ae) { 1231 TabActionEvent tae = (TabActionEvent) ae; 1232 if (!shouldPerformAction(tae.getActionCommand(), tae.getTabIndex(), tae.getMouseEvent())) { 1233 tae.consume(); 1234 } 1235 } 1236 } 1237 1238 private class SlidingTabsLayout implements LayoutManager { 1239 1240 public void addLayoutComponent(String name, Component comp) { 1241 } 1243 1244 public void layoutContainer(Container parent) { 1245 JComponent c = tabDisplayer; 1246 1247 Object orientation = c.getClientProperty ( 1248 TabDisplayer.PROP_ORIENTATION); 1249 1250 Dimension d = tabDisplayer.getPreferredSize(); 1251 Insets ins = container.getInsets(); 1252 int width = parent.getWidth() - (ins.left + ins.right); 1253 int height = parent.getHeight() - (ins.top + ins.bottom); 1254 1255 if (orientation == TabDisplayer.ORIENTATION_NORTH) { 1256 c.setBounds (ins.left, ins.top, 1257 width, d.height); 1258 1259 contentDisplayer.setBounds (ins.left, ins.top + d.height, 1260 width, 1261 parent.getHeight() - (d.height + ins.top + ins.bottom)); 1262 1263 } else if (orientation == TabDisplayer.ORIENTATION_SOUTH) { 1264 contentDisplayer.setBounds (ins.top, ins.left, width, 1265 parent.getHeight() - (d.height + ins.top + ins.bottom)); 1266 1267 c.setBounds (ins.left, parent.getHeight() - (d.height + ins.top + ins.bottom), 1268 width, d.height); 1269 } else if (orientation == TabDisplayer.ORIENTATION_EAST) { 1270 contentDisplayer.setBounds (ins.left, ins.top, width - d.width, 1271 height); 1272 1273 c.setBounds (parent.getWidth() - (ins.right + d.width), ins.top, 1274 d.width, height); 1275 1276 } else if (orientation == TabDisplayer.ORIENTATION_WEST) { 1277 c.setBounds (ins.left, ins.top, d.width, height); 1278 1279 contentDisplayer.setBounds (ins.left + d.width, ins.top, 1280 width - d.width, height); 1281 1282 } else { 1283 throw new IllegalArgumentException ("Unknown orientation: " + orientation); 1284 } 1285 } 1286 1287 public Dimension minimumLayoutSize(Container parent) { 1288 JComponent c = tabDisplayer; 1289 1290 Object orientation = c.getClientProperty ( 1291 TabDisplayer.PROP_ORIENTATION); 1292 1293 Dimension tabSize = tabDisplayer.getPreferredSize(); 1294 Insets ins = container.getInsets(); 1295 1296 Dimension result = new Dimension (); 1297 1298 Dimension contentSize = contentDisplayer.getPreferredSize(); 1299 if (tabDisplayer.getSelectionModel().getSelectedIndex() == -1) { 1300 contentSize.width = 0; 1301 contentSize.height = 0; 1302 } 1303 1304 if (orientation == TabDisplayer.ORIENTATION_NORTH || orientation == TabDisplayer.ORIENTATION_SOUTH) { 1305 result.height = ins.top + ins.bottom + contentSize.height + tabSize.height; 1306 result.width = ins.left + ins.right + Math.max (contentSize.width, tabSize.width); 1307 } else { 1308 result.width = ins.left + ins.right + contentSize.width + tabSize.width; 1309 result.height = ins.top + ins.bottom + Math.max (contentSize.height, tabSize.height); 1310 } 1311 return result; 1312 } 1313 1314 public Dimension preferredLayoutSize(Container parent) { 1315 return minimumLayoutSize(parent); 1316 } 1317 1318 public void removeLayoutComponent(Component comp) { 1319 } 1321 } 1322 1323 1325 private final class NoOpFxProvider extends FxProvider { 1326 1327 public void cleanup() { 1328 } 1330 1331 protected void doFinish() { 1332 showComponent (comp); 1333 1334 } 1335 1336 protected void doStart() { 1337 finish(); 1338 } 1339 } 1340 1341 private final class ImageSlideFxProvider extends FxProvider implements ActionListener { 1342 private Timer timer = null; 1343 private Component prevGlassPane = null; 1344 private Dimension d = null; 1345 1346 protected void doStart() { 1347 if (timer == null) { 1348 timer = new Timer (TIMER, this); 1349 timer.setRepeats(true); 1350 } 1351 1352 prevGlassPane = root.getGlassPane(); 1353 1354 if (prevGlassPane.isVisible() && prevGlassPane.isShowing()) { 1355 doFinish(); 1357 return; 1358 } 1359 1360 initSize(); 1361 img = createImageOfComponent(); 1362 1363 1364 ImageScalingGlassPane cp = getCustomGlassPane(); 1365 root.setGlassPane (cp); 1366 cp.setIncrement (0.1f); 1367 cp.setBounds (root.getBounds()); 1368 cp.setVisible(true); 1369 cp.revalidate(); 1370 timer.start(); 1371 } 1372 1373 public void cleanup() { 1374 timer.stop(); 1375 root.setGlassPane(prevGlassPane); 1376 prevGlassPane.setVisible(false); 1377 if (img != null) { 1378 img.flush(); 1379 } 1380 img = null; 1381 } 1382 1383 protected void doFinish() { 1384 showComponent (comp); 1385 } 1386 1387 private void initSize() { 1388 d = comp.getPreferredSize(); 1389 1390 Dimension d2 = contentDisplayer.getSize(); 1391 1392 d.width = Math.max (d2.width, d.width); 1393 d.height = Math.max (d2.height, d.height); 1394 1395 1396 boolean flip = orientation == TabDisplayer.ORIENTATION_EAST || 1397 orientation == TabDisplayer.ORIENTATION_WEST; 1398 1399 if (d.width == 0 || d.height == 0) { 1400 if (flip) { 1401 d.width = root.getWidth(); 1402 d.height = tabDisplayer.getHeight(); 1403 } else { 1404 d.width = tabDisplayer.getWidth(); 1405 d.height = root.getHeight(); 1406 } 1407 } else { 1408 if (flip) { 1409 d.height = Math.max (d.height, tabDisplayer.getHeight()); 1410 } else { 1411 d.width = Math.max (d.width, tabDisplayer.getWidth()); 1412 } 1413 } 1414 } 1415 1416 private BufferedImage img = null; 1417 private BufferedImage createImageOfComponent() { 1418 if (USE_SWINGPAINTING) { 1419 return null; 1420 } 1421 if (d.width == 0 || d.height == 0) { 1422 finish(); 1425 } 1426 1427 BufferedImage img = 1428 GraphicsEnvironment.getLocalGraphicsEnvironment(). 1429 getDefaultScreenDevice().getDefaultConfiguration(). 1430 createCompatibleImage(d.width, d.height); 1431 1432 Graphics2D g2d = img.createGraphics(); 1433 JComponent c = tabDisplayer; 1434 1435 c.setBounds (0, 0, d.width, d.height); 1436 comp.paint (g2d); 1437 1438 return img; 1439 } 1440 1441 public void actionPerformed(java.awt.event.ActionEvent e) { 1442 float inc = customGlassPane.getIncrement(); 1443 if (inc >= 1.0f) { 1444 finish(); 1445 } else { 1446 customGlassPane.setIncrement (inc + INCREMENT); 1447 } 1448 } 1449 1450 private ImageScalingGlassPane customGlassPane = null; 1451 private ImageScalingGlassPane getCustomGlassPane() { 1452 if (customGlassPane == null) { 1453 customGlassPane = new ImageScalingGlassPane(); 1454 customGlassPane.setOpaque(false); 1455 } 1456 return customGlassPane; 1457 } 1458 1459 private class ImageScalingGlassPane extends JPanel { 1460 private float inc = 0f; 1461 private Rectangle rect = new Rectangle (); 1462 private Rectangle r2 = new Rectangle (); 1463 private boolean changed = true; 1464 1465 private void setIncrement (float inc) { 1466 this.inc = inc; 1467 changed = true; 1468 if (isShowing()) { 1469 Rectangle r = getImageBounds(); 1470 if (SYNCHRONOUS_PAINTING) { 1471 paintImmediately (r.x, r.y, r.width, r.height); 1472 } else { 1473 repaint(r.x, r.y, r.width, r.height); 1474 } 1475 } 1476 } 1477 1478 private float getIncrement () { 1479 return inc; 1480 } 1481 1482 private Rectangle getImageBounds() { 1483 if (!changed) { 1484 return rect; 1485 } 1486 Component c = tabDisplayer; 1487 r2.setBounds (0, 0, c.getWidth(), c.getHeight()); 1488 1489 Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, 1490 this); 1491 1492 if (orientation == TabDisplayer.ORIENTATION_WEST) { 1493 rect.x = dispBounds.x + dispBounds.width; 1494 rect.y = dispBounds.y; 1495 rect.width = Math.round (inc * d.width); 1496 rect.height = dispBounds.height; 1497 } else if (orientation == TabDisplayer.ORIENTATION_EAST) { 1498 rect.width = Math.round (inc * d.width); 1499 rect.height = dispBounds.height; 1500 rect.x = dispBounds.x - rect.width; 1501 rect.y = dispBounds.y; 1502 } else if (orientation == TabDisplayer.ORIENTATION_SOUTH) { 1503 rect.width = dispBounds.width; 1504 rect.height = Math.round(inc * d.height); 1505 rect.x = dispBounds.x; 1506 rect.y = dispBounds.y - rect.height; 1507 } else if (orientation == TabDisplayer.ORIENTATION_NORTH) { 1508 rect.x = dispBounds.x; 1509 rect.y = dispBounds.y + dispBounds.height; 1510 rect.width = dispBounds.width; 1511 rect.height = Math.round(inc * d.height); 1512 } 1513 changed = false; 1514 return rect; 1515 } 1516 1517 public void paint(Graphics g) { 1518 try { 1519 if (USE_SWINGPAINTING) { 1520 SwingUtilities.paintComponent(g, comp, this, getImageBounds()); 1521 } else { 1522 Graphics2D g2d = (Graphics2D ) g; 1523 Composite comp = null; 1524 if (true) { 1525 comp = g2d.getComposite(); 1526 g2d.setComposite (AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Math.min(0.99f, inc))); 1527 } 1528 Rectangle r = getImageBounds(); 1529 if (NO_SCALE) { 1530 AffineTransform at = AffineTransform.getTranslateInstance(r.x, r.y); 1531 g2d.drawRenderedImage(img, at); 1532 } else { 1533 g2d.drawImage (img, r.x, r.y, r.x + r.width, 1534 r.y + r.height, 0, 0, d.width, d.height, 1535 getBackground(), null); 1536 } 1537 if (comp != null) { 1538 g2d.setComposite(comp); 1539 } 1540 } 1541 } catch (Exception e) { 1542 e.printStackTrace(); 1544 finish(); 1545 } 1546 } 1547 } 1548 } 1549 1550 1551 private final class LiveComponentSlideFxProvider extends FxProvider implements ActionListener { 1552 private Timer timer = null; 1553 private Component prevGlassPane = null; 1554 private Dimension d = null; 1555 1556 protected void doStart() { 1557 if (timer == null) { 1558 timer = new Timer (TIMER, this); 1559 timer.setRepeats(true); 1560 } 1561 1562 prevGlassPane = root.getGlassPane(); 1563 if (prevGlassPane.isVisible() && prevGlassPane.isShowing()) { 1564 doFinish(); 1566 return; 1567 } 1568 1569 initSize(); 1570 LiveComponentResizingGlassPane cp = getCustomGlassPane(); 1571 root.setGlassPane (cp); 1572 cp.setIncrement (0.1f); 1573 cp.setBounds (root.getBounds()); 1574 cp.setVisible(true); 1575 cp.revalidate(); 1576 timer.start(); 1577 } 1578 1579 private void initSize() { 1580 d = comp.getPreferredSize(); 1581 1582 Dimension d2 = contentDisplayer.getSize(); 1583 1584 d.width = Math.max (d2.width, d.width); 1585 d.height = Math.max (d2.height, d.height); 1586 1587 boolean flip = orientation == TabDisplayer.ORIENTATION_EAST || 1588 orientation == TabDisplayer.ORIENTATION_WEST; 1589 1590 if (d.width == 0 || d.height == 0) { 1591 if (flip) { 1592 d.width = root.getWidth(); 1593 d.height = tabDisplayer.getHeight(); 1594 } else { 1595 d.width = tabDisplayer.getWidth(); 1596 d.height = root.getHeight(); 1597 } 1598 } else { 1599 if (flip) { 1600 d.height = Math.max (d.height, tabDisplayer.getHeight()); 1601 } else { 1602 d.width = Math.max (d.width, tabDisplayer.getWidth()); 1603 } 1604 } 1605 } 1606 1607 public void cleanup() { 1608 timer.stop(); 1609 root.setGlassPane(prevGlassPane); 1610 prevGlassPane.setVisible(false); 1611 customGlassPane.remove(comp); 1612 } 1613 1614 protected void doFinish() { 1615 showComponent (comp); 1616 } 1617 1618 public void actionPerformed(java.awt.event.ActionEvent e) { 1619 float inc = customGlassPane.getIncrement(); 1620 if (inc >= 1.0f) { 1621 finish(); 1622 } else { 1623 customGlassPane.setIncrement (inc + INCREMENT); 1624 } 1625 } 1626 1627 private LiveComponentResizingGlassPane customGlassPane = null; 1628 private LiveComponentResizingGlassPane getCustomGlassPane() { 1629 if (customGlassPane == null) { 1630 customGlassPane = new LiveComponentResizingGlassPane(); 1631 customGlassPane.setOpaque(false); 1632 } 1633 return customGlassPane; 1634 } 1635 1636 private class LiveComponentResizingGlassPane extends JPanel { 1637 private float inc = 0f; 1638 private Rectangle rect = new Rectangle (); 1639 private Rectangle r2 = new Rectangle (); 1640 private boolean changed = true; 1641 1642 private void setIncrement (float inc) { 1643 this.inc = inc; 1644 changed = true; 1645 if (isShowing()) { 1646 if (comp.getParent() != this) { 1647 add(comp); 1648 comp.setVisible(true); 1649 } 1650 } 1651 doLayout(); 1652 } 1653 1654 public void doLayout() { 1655 Rectangle r = getImageBounds(); 1656 comp.setBounds (r.x, r.y, r.width, r.height); 1657 } 1658 1659 private float getIncrement () { 1660 return inc; 1661 } 1662 1663 private Rectangle getImageBounds() { 1664 if (!changed) { 1665 return rect; 1666 } 1667 Component c = tabDisplayer; 1668 r2.setBounds (0, 0, c.getWidth(), c.getHeight()); 1669 1670 Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, 1671 this); 1672 1673 if (orientation == TabDisplayer.ORIENTATION_WEST) { 1674 rect.x = dispBounds.x + dispBounds.width; 1675 rect.y = dispBounds.y; 1676 rect.width = Math.round (inc * d.width); 1677 rect.height = dispBounds.height; 1678 } else if (orientation == TabDisplayer.ORIENTATION_EAST) { 1679 rect.width = Math.round (inc * d.width); 1680 rect.height = dispBounds.height; 1681 rect.x = dispBounds.x - rect.width; 1682 rect.y = dispBounds.y; 1683 } else if (orientation == TabDisplayer.ORIENTATION_SOUTH) { 1684 rect.width = dispBounds.width; 1685 rect.height = Math.round(inc * d.height); 1686 rect.x = dispBounds.x; 1687 rect.y = dispBounds.y - rect.height; 1688 } else if (orientation == TabDisplayer.ORIENTATION_NORTH) { 1689 rect.x = dispBounds.x; 1690 rect.y = dispBounds.y + dispBounds.height; 1691 rect.width = dispBounds.width; 1692 rect.height = Math.round(inc * d.height); 1693 } 1694 changed = false; 1695 return rect; 1696 } 1697 } 1698 } 1699 1700 1702 1703 static final boolean NO_EFFECTS = Boolean.getBoolean ("nb.tabcontrol.no.fx"); 1705 static final boolean NO_SCALE = Boolean.getBoolean ("nb.tabcontrol.fx.no.scaling"); 1707 static final boolean USE_SWINGPAINTING = Boolean.getBoolean ("nb.tabcontrol.fx.swingpainting"); 1710 static final boolean ADD_TO_GLASSPANE = Boolean.getBoolean ("nb.tabcontrol.fx.use.resizing"); 1713 static final boolean EFFECTS_EVERYWHERE = Boolean.getBoolean ("nb.tabcontrol.fx.everywhere") || 1714 Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); 1716 1717 static final boolean USE_ALPHA = Boolean.getBoolean ("nb.tabcontrol.fx.use.alpha") || 1718 Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); 1720 static boolean SYNCHRONOUS_PAINTING = Boolean.getBoolean ("nb.tabcontrol.fx.synchronous"); 1722 static float INCREMENT = 0.07f; 1723 1724 static int TIMER = 25; 1725 static { 1726 boolean gratuitous = Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); String s = System.getProperty ("nb.tabcontrol.fx.increment"); if (s != null) { 1729 try { 1730 INCREMENT = Float.parseFloat(s); 1731 } catch (Exception e) { 1732 System.err.println("Bad float value specified: \"" + s +"\""); } 1734 } else if (gratuitous) { 1735 INCREMENT = 0.02f; 1736 } 1737 1738 s = System.getProperty ("nb.tabcontrol.fx.timer"); if (s != null) { 1740 try { 1741 TIMER = Integer.parseInt (s); 1742 } catch (Exception e) { 1743 System.err.println("Bad integer value specified: \"" + s + "\""); } 1745 } else if (gratuitous) { 1746 TIMER = 7; 1747 } 1748 if (gratuitous) { 1749 SYNCHRONOUS_PAINTING = true; 1750 } 1751 } 1752 1753 private static final class ForwardingMouseListener implements MouseListener { 1754 private final Container c; 1755 public ForwardingMouseListener (Container c) { 1756 this.c = c; 1757 } 1758 public void mousePressed (MouseEvent me) { 1759 forward (me); 1760 } 1761 1762 public void mouseReleased (MouseEvent me) { 1763 forward (me); 1764 } 1765 1766 public void mouseClicked (MouseEvent me) { 1767 forward (me); 1768 } 1769 1770 public void mouseEntered (MouseEvent me) { 1771 forward (me); 1772 } 1773 1774 public void mouseExited (MouseEvent me) { 1775 forward (me); 1776 } 1777 1778 private void forward (MouseEvent me) { 1779 MouseListener [] ml = c.getMouseListeners(); 1780 if (ml.length == 0 || me.isConsumed()) { 1781 return; 1782 } 1783 MouseEvent me2 = SwingUtilities.convertMouseEvent( 1784 (Component ) me.getSource(), me, c); 1785 1786 for (int i=0; i < ml.length; i++) { 1787 switch (me2.getID()) { 1788 case MouseEvent.MOUSE_ENTERED : 1789 ml[i].mouseEntered(me2); 1790 break; 1791 case MouseEvent.MOUSE_EXITED : 1792 ml[i].mouseExited(me2); 1793 break; 1794 case MouseEvent.MOUSE_PRESSED : 1795 ml[i].mousePressed(me2); 1796 break; 1797 case MouseEvent.MOUSE_RELEASED : 1798 ml[i].mouseReleased(me2); 1799 break; 1800 case MouseEvent.MOUSE_CLICKED : 1801 ml[i].mouseClicked(me2); 1802 break; 1803 default : 1804 assert false; 1805 } 1806 } 1807 } 1808 1809 } 1810} 1811 | Popular Tags |