diff --git a/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java b/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java --- a/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java +++ b/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java @@ -43,7 +43,6 @@ */ package org.netbeans.swing.tabcontrol.plaf; - import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Component; @@ -97,108 +96,143 @@ import org.netbeans.swing.tabcontrol.event.ComplexListDataListener; import org.netbeans.swing.tabcontrol.event.TabActionEvent; import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent; +import org.netbeans.swing.tabcontrol.plaf.EqualPolygon; +import org.netbeans.swing.tabcontrol.plaf.FxProvider; /** - * Default UI implementation for tabbed containers. Manages installing the tab - * contentDisplayer and content contentDisplayer components, and the - * relationship between the data models and selection models of the UI. - *

- * Note that there is typically little reasons to subclass this - to affect the display - * or behavior of the tabs, implement {@link org.netbeans.swing.tabcontrol.TabDisplayerUI}, - * the UI delegate for the embedded component which displays the tabs. * - * @author Tim Boudreau + * @author russell */ public class DefaultTabbedContainerUI extends TabbedContainerUI { + /** - * Action listener which receives actions from the tab displayer and propagates them through - * action listeners on the tab displayer, to allow clients to consume the events. + * Action listener which receives actions from the tab displayer and + * propagates them through action listeners on the tab displayer, to allow + * clients to consume the events. */ private ActionListener actionListener = null; /** - * Flag to ensure listeners attached, since ComponentShown notifications are not always - * reliable. + * Flag to ensure listeners attached, since ComponentShown notifications are + * not always reliable. */ - /** UIManager key for the border of the tab displayer in editor ui type. */ + /** + * UIManager key for the border of the tab displayer in editor ui type. + */ public static final String KEY_EDITOR_CONTENT_BORDER = "TabbedContainer.editor.contentBorder"; //NOI18N - /** UIManager key for the border of the tab displayer in editor ui type */ + /** + * UIManager key for the border of the tab displayer in editor ui type + */ public static final String KEY_EDITOR_TABS_BORDER = "TabbedContainer.editor.tabsBorder"; //NOI18N - /** UIManager key for the border of the entire tabbed container in editor ui type*/ + /** + * UIManager key for the border of the entire tabbed container in editor ui + * type + */ public static final String KEY_EDITOR_OUTER_BORDER = "TabbedContainer.editor.outerBorder"; //NOI18N - /** UIManager key for the border of the tab displayer in view ui type. */ + /** + * UIManager key for the border of the tab displayer in view ui type. + */ public static final String KEY_VIEW_CONTENT_BORDER = "TabbedContainer.view.contentBorder"; //NOI18N - /** UIManager key for the border of the tab displayer in view ui type. */ + /** + * UIManager key for the border of the tab displayer in view ui type. + */ public static final String KEY_VIEW_TABS_BORDER = "TabbedContainer.view.tabsBorder"; //NOI18N - /** UIManager key for the border of the entire tabbed container in view ui type.*/ + /** + * UIManager key for the border of the entire tabbed container in view ui + * type. + */ public static final String KEY_VIEW_OUTER_BORDER = "TabbedContainer.view.outerBorder"; //NOI18N - /** UIManager key for the border of the tab displayer in sliding ui type. */ + /** + * UIManager key for the border of the tab displayer in sliding ui type. + */ public static final String KEY_SLIDING_CONTENT_BORDER = "TabbedContainer.sliding.contentBorder"; //NOI18N - /** UIManager key for the border of the tab displayer in sliding ui type */ + /** + * UIManager key for the border of the tab displayer in sliding ui type + */ public static final String KEY_SLIDING_TABS_BORDER = "TabbedContainer.sliding.tabsBorder"; //NOI18N - /** UIManager key for the border of the entire tabbed container in sliding ui type*/ + /** + * UIManager key for the border of the entire tabbed container in sliding ui + * type + */ public static final String KEY_SLIDING_OUTER_BORDER = "TabbedContainer.sliding.outerBorder"; //NOI18N - /** UIManager key for the border of the tab displayer in toolbar ui type. */ + /** + * UIManager key for the border of the tab displayer in toolbar ui type. + */ public static final String KEY_TOOLBAR_CONTENT_BORDER = "TabbedContainer.toolbar.contentBorder"; //NOI18N - /** UIManager key for the border of the tab displayer in toolbar ui type */ + /** + * UIManager key for the border of the tab displayer in toolbar ui type + */ public static final String KEY_TOOLBAR_TABS_BORDER = "TabbedContainer.toolbar.tabsBorder"; //NOI18N - /** UIManager key for the border of the entire tabbed container in toolbar ui type*/ + /** + * UIManager key for the border of the entire tabbed container in toolbar ui + * type + */ public static final String KEY_TOOLBAR_OUTER_BORDER = "TabbedContainer.toolbar.outerBorder"; //NOI18N - /** Component listener which listens on the container, and attaches/detaches listeners. - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. - **/ + /** + * Component listener which listens on the container, and attaches/detaches + * listeners. + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. + * + */ protected ComponentListener componentListener = null; - /** Change listener which tracks changes in the selection model and changes the displayed - * component to reflect the selected tab - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. + /** + * Change listener which tracks changes in the selection model and changes + * the displayed component to reflect the selected tab + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. */ protected ChangeListener selectionListener = null; - /** Listener on the data model, which handles updating the contained components to keep them - * in sync with the contents of the data model. - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. + /** + * Listener on the data model, which handles updating the contained + * components to keep them in sync with the contents of the data model. + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. + * * @see TabbedContainer#setContentPolicy */ protected ComplexListDataListener modelListener = null; /** * Layout manager which will handle layout of the tabbed container. - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. */ protected LayoutManager contentDisplayerLayout = null; - /** Property change listener which detects changes on the tabbed container, such as its active state, which - * should be propagated to the tab displayer. - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. + /** + * Property change listener which detects changes on the tabbed container, + * such as its active state, which should be propagated to the tab + * displayer. + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. */ protected PropertyChangeListener propertyChangeListener = null; /** - * FxProvider which will provide transition effects when tabs are changed. By default, only used for - * TabbedContainer.TYPE_SLIDE tabs. - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. + * FxProvider which will provide transition effects when tabs are changed. + * By default, only used for TabbedContainer.TYPE_SLIDE tabs. + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. */ protected FxProvider slideEffectManager = null; /** - * The component which displays the selected component in the tabbed container. - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. + * The component which displays the selected component in the tabbed + * container. + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. */ protected JComponent contentDisplayer = null; /** - * The Displayer for the tabs. Normally an instance of TabDisplayer. To get the actual - * GUI component that is showing tabs, call its getComponent() method. - * do not alter the value in this field. To provide a different implementation, - * override the appropriate creation method. + * The Displayer for the tabs. Normally an instance of + * TabDisplayer. To get the actual GUI component that is + * showing tabs, call its getComponent() method. + * do not alter the value in this field. To provide a different + * implementation, override the appropriate creation method. */ protected TabDisplayer tabDisplayer = null; - + private HierarchyListener hierarchyListener = null; /** @@ -212,18 +246,20 @@ return new DefaultTabbedContainerUI((TabbedContainer) c); } - /** This method is final. Subclasses which need to provide additional initialization should override - * install() + /** + * This method is final. Subclasses which need to provide additional + * initialization should override install() * - * @param c A JComponent, which must == the displayer field initialized in the constructor + * @param c A JComponent, which must == the displayer field initialized in + * the constructor */ @Override public final void installUI(JComponent c) { assert c == container; container.setLayout(createLayout()); contentDisplayer = createContentDisplayer(); - if( "Aqua".equals(UIManager.getLookAndFeel().getID()) //NOI18N - && (container.getType() == TabbedContainer.TYPE_VIEW + if ("Aqua".equals(UIManager.getLookAndFeel().getID()) //NOI18N + && (container.getType() == TabbedContainer.TYPE_VIEW || container.getType() == TabbedContainer.TYPE_SLIDING) && !Boolean.getBoolean("nb.explorerview.aqua.defaultbackground")) { //NOI18N contentDisplayer.setBackground(UIManager.getColor("NbExplorerView.background")); //NOI18N @@ -250,20 +286,24 @@ tabDisplayer.getSelectionModel().addChangeListener(selectionListener); } - - - /** Used by unit tests */ + + /** + * Used by unit tests + */ TabDisplayer getTabDisplayer() { return tabDisplayer; } private MouseListener forward = null; - /** This method is final. Subclasses which need to provide additional initialization should override - * uninstall() + /** + * This method is final. Subclasses which need to provide additional + * initialization should override uninstall() * - * @param c A JComponent, which must == the displayer field initialized in the constructor + * @param c A JComponent, which must == the displayer field initialized in + * the constructor */ + @Override public final void uninstallUI(JComponent c) { assert c == container; tabDisplayer.getSelectionModel().removeChangeListener(selectionListener); @@ -283,25 +323,29 @@ forward = null; } - /** Subclasses may override this method to do anything they need to do on installUI(). It will - * be called after listeners, the displayer, etc. (all pseudo-final protected fields) have been - * initialized. + /** + * Subclasses may override this method to do anything they need to do on + * installUI(). It will be called after listeners, the displayer, etc. (all + * pseudo-final protected fields) have been initialized. */ protected void install() { } - /** Subclasses may override this method to do anything they need to do on uninstallUI(). It will - * be called before the protected fields of the instance have been nulled. + /** + * Subclasses may override this method to do anything they need to do on + * uninstallUI(). It will be called before the protected fields of the + * instance have been nulled. */ protected void uninstall() { } - + + @Override protected boolean uichange() { installBorders(); return false; - } + } /** * Installs the content displayer component and its layout manager @@ -312,8 +356,8 @@ } /** - * Installs the tab displayer component into the container. By default, installs it using the - * constraint BorderLayout.NORTH. + * Installs the tab displayer component into the container. By default, + * installs it using the constraint BorderLayout.NORTH. */ protected void installTabDisplayer() { container.add(tabDisplayer, BorderLayout.NORTH); @@ -328,69 +372,70 @@ String contentKey; String outerKey; switch (container.getType()) { - case TabbedContainer.TYPE_EDITOR : + case TabbedContainer.TYPE_EDITOR: tabsKey = KEY_EDITOR_TABS_BORDER; contentKey = KEY_EDITOR_CONTENT_BORDER; outerKey = KEY_EDITOR_OUTER_BORDER; break; - case TabbedContainer.TYPE_VIEW : + case TabbedContainer.TYPE_VIEW: tabsKey = KEY_VIEW_TABS_BORDER; contentKey = KEY_VIEW_CONTENT_BORDER; outerKey = KEY_VIEW_OUTER_BORDER; break; - case TabbedContainer.TYPE_SLIDING : + case TabbedContainer.TYPE_SLIDING: tabsKey = KEY_SLIDING_TABS_BORDER; contentKey = KEY_SLIDING_CONTENT_BORDER; outerKey = KEY_SLIDING_OUTER_BORDER; break; - case TabbedContainer.TYPE_TOOLBAR : + case TabbedContainer.TYPE_TOOLBAR: tabsKey = KEY_TOOLBAR_TABS_BORDER; contentKey = KEY_TOOLBAR_CONTENT_BORDER; outerKey = KEY_TOOLBAR_OUTER_BORDER; break; - default : - throw new IllegalStateException ("Unknown type: " - + container.getType()); + default: + throw new IllegalStateException("Unknown type: " + + container.getType()); } try { - Border b = (Border) UIManager.get (contentKey); + Border b = (Border) UIManager.get(contentKey); contentDisplayer.setBorder(b); - b = (Border) UIManager.get (tabsKey); + b = (Border) UIManager.get(tabsKey); tabDisplayer.setBorder(b); - b = (Border) UIManager.get (outerKey); + b = (Border) UIManager.get(outerKey); container.setBorder(b); } catch (ClassCastException cce) { - System.err.println ("Expected a border from UIManager for " - + tabsKey + "," + contentKey + "," + outerKey); + System.err.println("Expected a border from UIManager for " + + tabsKey + "," + contentKey + "," + outerKey); } } /** - * Installs a component listener on the component. Listeners on the data + * Installs a component listener on the component. Listeners on the data * model and selection model are installed when the component is shown, as * detected by the component listener. */ protected void installListeners() { container.addComponentListener(componentListener); - container.addHierarchyListener (hierarchyListener); + container.addHierarchyListener(hierarchyListener); //Allow mouse events to be forwarded as if they came from the //container - tabDisplayer.addMouseListener (forward); - contentDisplayer.addMouseListener (forward); + tabDisplayer.addMouseListener(forward); + contentDisplayer.addMouseListener(forward); } /** * Begin listening to the model for changes in the selection, which should * cause us to update the displayed component in the content * contentDisplayer. Listening starts when the component is first shown, and - * stops when it is hidden; if you override createComponentListener(), - * you will need to call this method when the component is shown. + * stops when it is hidden; if you override + * createComponentListener(), you will need to call this method + * when the component is shown. */ protected void attachModelAndSelectionListeners() { container.getModel().addComplexListDataListener(modelListener); container.addPropertyChangeListener(propertyChangeListener); - tabDisplayer.setActive (container.isActive()); - tabDisplayer.addActionListener (actionListener); + tabDisplayer.setActive(container.isActive()); + tabDisplayer.addActionListener(actionListener); } /** @@ -398,25 +443,27 @@ * cause us to update the displayed component in the content * contentDisplayer, and changes in the data model which can affect the * displayed component. Listening starts when the component is first shown, - * and stops when it is hidden; if you override createComponentListener(), - * you will need to call this method when the component is hidden. + * and stops when it is hidden; if you override + * createComponentListener(), you will need to call this method + * when the component is hidden. */ protected void detachModelAndSelectionListeners() { container.getModel().removeComplexListDataListener(modelListener); container.removePropertyChangeListener(propertyChangeListener); - tabDisplayer.removeActionListener (actionListener); + tabDisplayer.removeActionListener(actionListener); } /** - * Uninstalls the component listener installed in installListeners() + * Uninstalls the component listener installed in + * installListeners() */ protected void uninstallListeners() { container.removeComponentListener(componentListener); - container.removeHierarchyListener (hierarchyListener); + container.removeHierarchyListener(hierarchyListener); componentListener = null; propertyChangeListener = null; - tabDisplayer.removeMouseListener (forward); - contentDisplayer.removeMouseListener (forward); + tabDisplayer.removeMouseListener(forward); + contentDisplayer.removeMouseListener(forward); } /** @@ -447,24 +494,25 @@ container.getModel(), container.getType(), container.getLocationInformer()); } result.setName("Tab Displayer"); //NOI18N - result.setComponentConverter( container.getComponentConverter() ); + result.setComponentConverter(container.getComponentConverter()); return result; } /** * Create the component which will contain the content (the components which - * correspond to tabs). The default implementation simply returns a - * vanilla, unadorned JPanel. + * correspond to tabs). The default implementation simply returns a vanilla, + * unadorned JPanel. */ protected JPanel createContentDisplayer() { JPanel result = new JPanel(); - result.setName ("Content displayer"); //NOI18N + result.setName("Content displayer"); //NOI18N return result; } /** - * Create an FxProvider instance which will provide transition effects when tabs are selected. - * By default creates a no-op instance for all displayer types except TYPE_SLIDING. + * Create an FxProvider instance which will provide transition effects when + * tabs are selected. By default creates a no-op instance for all displayer + * types except TYPE_SLIDING. * * @return An instance of FxProvider */ @@ -482,8 +530,7 @@ /** * Creates the content contentDisplayer's layout manager, responsible for - * ensuring that the correct component is on top and is the only one - * showing + * ensuring that the correct component is on top and is the only one showing */ protected LayoutManager createContentDisplayerLayout() { return new StackLayout(); @@ -491,13 +538,13 @@ /** * Create the layout manager that will manage the layout of the - * TabbedContainer. A TabbedContainer contains two components - the tabs + * TabbedContainer. A TabbedContainer contains two components - the tabs * contentDisplayer, and the component contentDisplayer. *

* The layout manager determines the position of the tabs relative to the * contentDisplayer component which displays the tab contents. *

- * The default implementation uses BorderLayout. If you override this, you + * The default implementation uses BorderLayout. If you override this, you * should probably override installDisplayer() as well. */ protected LayoutManager createLayout() { @@ -520,16 +567,18 @@ /** * Create a property change listener which will update the tab displayer in - * accordance with property changes on the container. Currently the only - * property change of interest is calls to TabbedContainer.setActive(), - * which simply cause the active state to be set on the displayer. + * accordance with property changes on the container. Currently the only + * property change of interest is calls to + * TabbedContainer.setActive(), which simply cause the active + * state to be set on the displayer. */ protected PropertyChangeListener createPropertyChangeListener() { return new ContainerPropertyChangeListener(); } - /** Creates an action listener to catch actions performed on the tab displayer - * and forward them to listeners on the container for consumption. + /** + * Creates an action listener to catch actions performed on the tab + * displayer and forward them to listeners on the container for consumption. * * @return An action listener */ @@ -548,17 +597,19 @@ showComponent(toComp(td)); } } - - /** Convenience method for fetching a component from a TabData object - * via the container's ComponentConverter */ - protected final Component toComp (TabData data) { + + /** + * Convenience method for fetching a component from a TabData object via the + * container's ComponentConverter + */ + protected final Component toComp(TabData data) { return container.getComponentConverter().getComponent(data); } /** * Shows the passed component. This method does not communicate with * the data model in any way shape or form, it just moves the passed - * component to the front. It should only be called in response to an event + * component to the front. It should only be called in response to an event * from the data model or selection model. *

* If you override createContentDisplayerLayoutModel() to @@ -575,7 +626,7 @@ Component last = stack.getVisibleComponent(); stack.showComponent(c, contentDisplayer); if (c != null) { - Integer offset = (Integer)((JComponent)c).getClientProperty("MultiViewBorderHack.topOffset"); + Integer offset = (Integer) ((JComponent) c).getClientProperty("MultiViewBorderHack.topOffset"); contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", offset); } else { contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", null); @@ -589,33 +640,35 @@ } /** - * Shows a component in the control, using the FxProvider created in - * createFxProvider() to manage showing it. Equivalent to calling showComponent, - * but there may be a delay while the effect is performed. If no FxProvider is installed, - * this will simply delegate to showComponent; if not, the FxProvider is expected - * to do that when its effect is completed. + * Shows a component in the control, using the FxProvider + * created in createFxProvider() to manage showing it. + * Equivalent to calling showComponent, but there may be a + * delay while the effect is performed. If no FxProvider is + * installed, this will simply delegate to showComponent; if + * not, the FxProvider is expected to do that when its effect + * is completed. * * @param c The component to be shown. */ - protected final void showComponentWithFxProvider (Component c) { + protected final void showComponentWithFxProvider(Component c) { if (slideEffectManager == null || !container.isShowing() || (!(c instanceof JComponent))) { - Component last = showComponent (c); - maybeRemoveLastComponent (last); + Component last = showComponent(c); + maybeRemoveLastComponent(last); } else { - slideEffectManager.start((JComponent) c, container.getRootPane(), - tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION)); + slideEffectManager.start((JComponent) c, container.getRootPane(), + tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION)); } } /** - * Removes the passed component from the AWT hierarchy if the container's content policy is - * CONTENT_POLICY_ADD_ONLY_SELECTED. + * Removes the passed component from the AWT hierarchy if the container's + * content policy is CONTENT_POLICY_ADD_ONLY_SELECTED. * * @param c The component that should be removed */ - private final void maybeRemoveLastComponent (Component c) { + private final void maybeRemoveLastComponent(Component c) { if (c != null && container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ONLY_SELECTED) { - contentDisplayer.remove (c); + contentDisplayer.remove(c); } } @@ -627,8 +680,11 @@ List tabs = container.getModel().getTabs(); Component curC = null; for (Iterator iter = tabs.iterator(); iter.hasNext();) { - curC = toComp ((TabData) iter.next()); + curC = toComp((TabData) iter.next()); // string parameter is needed for StackLayout to kick in correctly + if (curC.getParent() != null) { + curC.getParent().remove(curC); + } contentDisplayer.add(curC, ""); } } else { @@ -642,9 +698,9 @@ } /** - * Create a listener for the TabDataModel. This listener is responsible for + * Create a listener for the TabDataModel. This listener is responsible for * keeping the state of the contained components in the displayer in sync - * with the contents of the data model. Note that it is not necessary for + * with the contents of the data model. Note that it is not necessary for * this listener to adjust the selection - DefaultTabSelectionModel handles * cases such as removing the selected component appropriately, so if such a * model change happens, a selection change will be immediately forthcoming @@ -669,7 +725,9 @@ return new SelectionListener(); } - /** Sets the active state of the displayer to match that of the container */ + /** + * Sets the active state of the displayer to match that of the container + */ private void updateActiveState() { //#45630 - more of a hack than a fix. //apparently uninstallUI() was called before the the ContainerPropertyChangeListener instance was removed in @@ -680,9 +738,10 @@ if (displ != null && cont != null) { displ.setActive(cont.isActive()); } - + } + @Override public Rectangle getTabRect(int tab, Rectangle r) { if (r == null) { r = new Rectangle(); @@ -693,25 +752,29 @@ r.y += p.y; return r; } - - protected void requestAttention (int tab) { - tabDisplayer.requestAttention (tab); + + @Override + protected void requestAttention(int tab) { + tabDisplayer.requestAttention(tab); } - - protected void cancelRequestAttention (int tab) { + + @Override + protected void cancelRequestAttention(int tab) { tabDisplayer.cancelRequestAttention(tab); } @Override - protected void setAttentionHighlight (int tab, boolean highlight) { + protected void setAttentionHighlight(int tab, boolean highlight) { tabDisplayer.setAttentionHighlight(tab, highlight); } - - public void setShowCloseButton (boolean val) { + + @Override + public void setShowCloseButton(boolean val) { tabDisplayer.setShowCloseButton(val); } - - public boolean isShowCloseButton () { + + @Override + public boolean isShowCloseButton() { return tabDisplayer.isShowCloseButton(); } @@ -720,10 +783,12 @@ * border is provided via UIDefaults. */ private static final class DefaultWindowBorder implements Border { + private static final Insets insets = new Insets(1, 1, 2, 2); + @Override public void paintBorder(Component c, Graphics g, int x, int y, int w, - int h) { + int h) { g.translate(x, y); g.setColor(UIManager.getColor("controlShadow")); //NOI18N @@ -735,25 +800,29 @@ g.translate(-x, -y); } + @Override public Insets getBorderInsets(Component c) { return insets; } + @Override public boolean isBorderOpaque() { return true; } } // end of DefaultWindowBorder protected class ContainerPropertyChangeListener implements PropertyChangeListener { - + + @Override public void propertyChange(PropertyChangeEvent evt) { if (TabbedContainer.PROP_ACTIVE.equals(evt.getPropertyName())) { updateActiveState(); } } } - - /** Checks the position of the tabbed container relative to its parent + + /** + * Checks the position of the tabbed container relative to its parent * window, and potentially updates its orientation client property. * * @see TabDisplayer#PROP_ORIENTATION @@ -762,7 +831,7 @@ if (!container.isDisplayable()) { return; } - if (Boolean.FALSE.equals(container.getClientProperty (TabbedContainer.PROP_MANAGE_TAB_POSITION))) { + if (Boolean.FALSE.equals(container.getClientProperty(TabbedContainer.PROP_MANAGE_TAB_POSITION))) { //The client has specified that it does not want automatic management //of the displayer orientation return; @@ -797,46 +866,53 @@ if (currOrientation != orientation) { tabDisplayer.putClientProperty( - TabDisplayer.PROP_ORIENTATION, orientation); + TabDisplayer.PROP_ORIENTATION, orientation); container.validate(); } } + @Override public int tabForCoordinate(Point p) { p = SwingUtilities.convertPoint(container, p, tabDisplayer); return tabDisplayer.tabForCoordinate(p); } + @Override public void makeTabVisible(int tab) { - tabDisplayer.makeTabVisible (tab); + tabDisplayer.makeTabVisible(tab); } + @Override public SingleSelectionModel getSelectionModel() { return tabDisplayer.getSelectionModel(); } + @Override public Image createImageOfTab(int idx) { return tabDisplayer.getUI().createImageOfTab(idx); } + @Override public Polygon getExactTabIndication(int idx) { Polygon result = tabDisplayer.getUI().getExactTabIndication(idx); - scratchPoint.setLocation(0,0); + scratchPoint.setLocation(0, 0); Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container); - result.translate (-p.x, -p.y); + result.translate(-p.x, -p.y); return appendContentBoundsTo(result); } private Point scratchPoint = new Point(); + + @Override public Polygon getInsertTabIndication(int idx) { Polygon result = tabDisplayer.getUI().getInsertTabIndication(idx); - scratchPoint.setLocation(0,0); + scratchPoint.setLocation(0, 0); Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container); - result.translate (-p.x, -p.y); + result.translate(-p.x, -p.y); return appendContentBoundsTo(result); } - private Polygon appendContentBoundsTo (Polygon p) { + private Polygon appendContentBoundsTo(Polygon p) { int width = contentDisplayer.getWidth(); int height = contentDisplayer.getHeight(); @@ -844,9 +920,8 @@ int[] ypoints = new int[xpoints.length]; //XXX not handling this correctly for non-top orientations - int pos = 0; - Object orientation = tabDisplayer.getClientProperty (TabDisplayer.PROP_ORIENTATION); + Object orientation = tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION); int tabsHeight = tabDisplayer.getHeight(); if (orientation == null || orientation == TabDisplayer.ORIENTATION_NORTH) { @@ -856,17 +931,17 @@ pos++; - xpoints[pos] = p.xpoints[p.npoints-1]; + xpoints[pos] = p.xpoints[p.npoints - 1]; ypoints[pos] = tabsHeight; pos++; - for (int i=0; i < p.npoints-2; i++) { - xpoints [pos] = p.xpoints[i]; - ypoints [pos] = p.ypoints[i]; + for (int i = 0; i < p.npoints - 2; i++) { + xpoints[pos] = p.xpoints[i]; + ypoints[pos] = p.ypoints[i]; pos++; } - xpoints[pos] = xpoints[pos-1]; + xpoints[pos] = xpoints[pos - 1]; ypoints[pos] = tabsHeight; pos++; @@ -877,7 +952,7 @@ pos++; xpoints[pos] = width - 1; - ypoints[pos] = height -1; + ypoints[pos] = height - 1; pos++; @@ -905,7 +980,7 @@ //Search backward for the upper right corner - we only know //the location of the left upper corner int highestFound = Integer.MIN_VALUE; - for (int i = p.npoints-2; i >= 0; i--) { + for (int i = p.npoints - 2; i >= 0; i--) { if (highestFound < p.ypoints[i]) { upperRight = i; highestFound = p.ypoints[i]; @@ -914,17 +989,17 @@ } } - int curr = upperRight-1; - for (int i=p.npoints-1; i >= 0; i--) { + int curr = upperRight - 1; + for (int i = p.npoints - 1; i >= 0; i--) { xpoints[pos] = p.xpoints[curr]; if (ypoints[pos] == highestFound) { - ypoints[pos] = Math.min (tabDisplayer.getLocation().y, p.ypoints[curr] + yxlate); + ypoints[pos] = Math.min(tabDisplayer.getLocation().y, p.ypoints[curr] + yxlate); } else { ypoints[pos] = p.ypoints[curr] + yxlate; } pos++; curr++; - if (curr == p.npoints-1) { + if (curr == p.npoints - 1) { curr = 0; } } @@ -937,21 +1012,24 @@ ypoints = p.ypoints; } - Polygon result = new EqualPolygon (xpoints, ypoints, xpoints.length); + Polygon result = new EqualPolygon(xpoints, ypoints, xpoints.length); return result; } + @Override public Rectangle getContentArea() { return contentDisplayer.getBounds(); } + @Override public Rectangle getTabsArea() { return tabDisplayer.getBounds(); } + @Override public int dropIndexOfPoint(Point p) { Point p2 = SwingUtilities.convertPoint(container, p, tabDisplayer); - return tabDisplayer.getUI().dropIndexOfPoint (p2); + return tabDisplayer.getUI().dropIndexOfPoint(p2); } public Rectangle getTabsArea(Rectangle dest) { @@ -963,31 +1041,38 @@ * selection and model listeners */ protected class ContainerComponentListener extends ComponentAdapter { + public ContainerComponentListener() { } - - public void componentMoved (ComponentEvent e) { + + @Override + public void componentMoved(ComponentEvent e) { if (container.getType() == TabbedContainer.TYPE_SLIDING) { updateOrientation(); } } - - public void componentResized (ComponentEvent e) { + + @Override + public void componentResized(ComponentEvent e) { if (container.getType() == TabbedContainer.TYPE_SLIDING) { updateOrientation(); } } } - + private boolean bug4924561knownShowing = false; + /** - * Calls initDisplayer(), then attachModelAndSelectionListeners, - * then ensureSelectedComponentIsShowing + * Calls initDisplayer(), then + * attachModelAndSelectionListeners, then + * ensureSelectedComponentIsShowing */ private class ContainerHierarchyListener implements HierarchyListener { + public ContainerHierarchyListener() { } - + + @Override public void hierarchyChanged(HierarchyEvent e) { if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { boolean showing = container.isShowing(); @@ -1010,56 +1095,61 @@ } } } - + private class ToolbarTabsLayout implements LayoutManager { - + + @Override public void layoutContainer(Container container) { Dimension tabSize = tabDisplayer.getPreferredSize(); Insets ins = container.getInsets(); int w = container.getWidth() - (ins.left + ins.right); - tabDisplayer.setBounds (ins.left, ins.top, - w, - tabSize.height); - if( tabDisplayer.getModel().size() > 1 ) { + tabDisplayer.setBounds(ins.left, ins.top, + w, + tabSize.height); + if (tabDisplayer.getModel().size() > 1) { //#214427 - check the preferred size again, during the first pass //the tab displayer may not know the available width Dimension newTabSize = tabDisplayer.getPreferredSize(); - if( newTabSize.height != tabSize.height ) { + if (newTabSize.height != tabSize.height) { tabSize = newTabSize; - tabDisplayer.setBounds (ins.left, ins.top, - w, - tabSize.height); + tabDisplayer.setBounds(ins.left, ins.top, + w, + tabSize.height); } } - contentDisplayer.setBounds(ins.left, - ins.top + tabSize.height, w, - container.getHeight() - (ins.top + ins.bottom + tabSize.height)); + contentDisplayer.setBounds(ins.left, + ins.top + tabSize.height, w, + container.getHeight() - (ins.top + ins.bottom + tabSize.height)); } - + + @Override public Dimension minimumLayoutSize(Container container) { Dimension tabSize = tabDisplayer.getMinimumSize(); Dimension contentSize = contentDisplayer.getMinimumSize(); Insets ins = container.getInsets(); Dimension result = new Dimension(ins.left + ins.top, ins.right + ins.bottom); - result.width += Math.max (tabSize.width, contentSize.width); + result.width += Math.max(tabSize.width, contentSize.width); result.height += tabSize.height + contentSize.height; return result; } - + + @Override public Dimension preferredLayoutSize(Container container) { Dimension tabSize = tabDisplayer.getPreferredSize(); Dimension contentSize = contentDisplayer.getPreferredSize(); Insets ins = container.getInsets(); Dimension result = new Dimension(ins.left + ins.top, ins.right + ins.bottom); - result.width += Math.max (tabSize.width, contentSize.width); + result.width += Math.max(tabSize.width, contentSize.width); result.height += tabSize.height + contentSize.height; return result; } - + + @Override public void removeLayoutComponent(Component component) { //do nothing } - + + @Override public void addLayoutComponent(String str, Component component) { //do nothing } @@ -1071,23 +1161,25 @@ * model */ protected class SelectionListener implements ChangeListener { + public SelectionListener() { } + @Override public void stateChanged(ChangeEvent e) { - if (container.isShowing() - //a special case for property sheet dialog window - the selection - //change must be processed otherwise the tabbed container may have - //undefined preferred size so the property window will be too small - || container.getClientProperty("tc") != null) { //NOI18N + if (container.isShowing() + //a special case for property sheet dialog window - the selection + //change must be processed otherwise the tabbed container may have + //undefined preferred size so the property window will be too small + || container.getClientProperty("tc") != null) { //NOI18N int idx = tabDisplayer.getSelectionModel().getSelectedIndex(); if (idx != -1) { Component c = toComp(container.getModel().getTab(idx)); c.setBounds(0, 0, contentDisplayer.getWidth(), - contentDisplayer.getHeight()); + contentDisplayer.getHeight()); showComponentWithFxProvider(c); } else { - showComponent (null); + showComponent(null); } } } @@ -1098,6 +1190,7 @@ * displayer up-to-date with the contents of the data model. */ protected class ModelListener implements ComplexListDataListener { + public ModelListener() { } @@ -1105,6 +1198,7 @@ * DefaultTabDataModel will always call this method with an instance of * ComplexListDataEvent. */ + @Override public void contentsChanged(ListDataEvent e) { //Only need to reread components on setTab (does winsys even use it?) if (e instanceof ComplexListDataEvent) { @@ -1115,14 +1209,17 @@ index); Component nue = toComp(tabDisplayer.getModel().getTab(index)); contentDisplayer.remove(comp); - - boolean add = - container.getContentPolicy() == - TabbedContainer.CONTENT_POLICY_ADD_ALL || - index == - container.getSelectionModel().getSelectedIndex(); - + + boolean add + = container.getContentPolicy() + == TabbedContainer.CONTENT_POLICY_ADD_ALL + || index + == container.getSelectionModel().getSelectedIndex(); + if (add) { + if (nue.getParent() != null) { + nue.getParent().remove(nue); + } contentDisplayer.add(nue, index); } } @@ -1134,7 +1231,7 @@ /** * This method is called to scroll the selected tab into view if its - * title changes (it may be scrolled offscreen). NetBeans' editor uses + * title changes (it may be scrolled offscreen). NetBeans' editor uses * this to ensure that the user can see what file they're editing when * the user starts typing (this triggers a * being appended to the tab * title, thus triggering this call). @@ -1156,17 +1253,21 @@ } } - + @Override public void intervalAdded(ListDataEvent e) { if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { Component curC = null; for (int i = e.getIndex0(); i <= e.getIndex1(); i++) { curC = toComp(container.getModel().getTab(i)); + if (curC.getParent() != null) { + curC.getParent().remove(curC); + } contentDisplayer.add(curC, ""); } } } + @Override public void intervalRemoved(ListDataEvent e) { // we know that it must be complex data event ComplexListDataEvent clde = (ComplexListDataEvent) e; @@ -1178,17 +1279,22 @@ } } + @Override public void indicesAdded(ComplexListDataEvent e) { Component curC = null; if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { int[] indices = e.getIndices(); for (int i = 0; i < indices.length; i++) { curC = toComp(container.getModel().getTab(indices[i])); + if (curC.getParent() != null) { + curC.getParent().remove(curC); + } contentDisplayer.add(curC, ""); } } } + @Override public void indicesRemoved(ComplexListDataEvent e) { int[] indices = e.getIndices(); TabData[] removedTabs = e.getAffectedItems(); @@ -1200,6 +1306,7 @@ } } + @Override public void indicesChanged(ComplexListDataEvent e) { //XXX - if we keep contentPolicies, this could be simplified for //the non ADD_ALL policies @@ -1245,9 +1352,9 @@ } } } - + if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) { - + //See if we've got anything to add if (!added.isEmpty()) { Iterator i = added.iterator(); @@ -1260,7 +1367,11 @@ //extra work if (!contentDisplayer.isAncestorOf( toComp(add))) { - contentDisplayer.add(toComp(add), ""); + Component curC = toComp(add); + if (curC.getParent() != null) { + curC.getParent().remove(curC); + } + contentDisplayer.add(curC, ""); changed = true; } } @@ -1276,12 +1387,16 @@ } } - /** An action listener which listens on action events from the tab displayer (select, close, etc.) - * and propagates them to the tabbed container's action posting mechanism, so listeners on it also - * have an opportunity to veto undesired actions, or handle actions themselves. + /** + * An action listener which listens on action events from the tab displayer + * (select, close, etc.) and propagates them to the tabbed container's + * action posting mechanism, so listeners on it also have an opportunity to + * veto undesired actions, or handle actions themselves. */ private class DisplayerActionListener implements ActionListener { - public void actionPerformed (ActionEvent ae) { + + @Override + public void actionPerformed(ActionEvent ae) { TabActionEvent tae = (TabActionEvent) ae; if (!shouldPerformAction(tae.getActionCommand(), tae.getTabIndex(), tae.getMouseEvent())) { tae.consume(); @@ -1290,116 +1405,128 @@ } private class SlidingTabsLayout implements LayoutManager { - + + @Override public void addLayoutComponent(String name, Component comp) { //do nothing } - + + @Override public void layoutContainer(Container parent) { JComponent c = tabDisplayer; - - Object orientation = c.getClientProperty ( - TabDisplayer.PROP_ORIENTATION); - + + Object orientation = c.getClientProperty( + TabDisplayer.PROP_ORIENTATION); + Dimension d = tabDisplayer.getPreferredSize(); Insets ins = container.getInsets(); int width = parent.getWidth() - (ins.left + ins.right); int height = parent.getHeight() - (ins.top + ins.bottom); - + if (orientation == TabDisplayer.ORIENTATION_NORTH) { - c.setBounds (ins.left, ins.top, - width, d.height); - - contentDisplayer.setBounds (ins.left, ins.top + d.height, - width, - parent.getHeight() - (d.height + ins.top + ins.bottom)); - + c.setBounds(ins.left, ins.top, + width, d.height); + + contentDisplayer.setBounds(ins.left, ins.top + d.height, + width, + parent.getHeight() - (d.height + ins.top + ins.bottom)); + } else if (orientation == TabDisplayer.ORIENTATION_SOUTH) { - contentDisplayer.setBounds (ins.top, ins.left, width, - parent.getHeight() - (d.height + ins.top + ins.bottom)); - - c.setBounds (ins.left, parent.getHeight() - (d.height + ins.top + ins.bottom), - width, d.height); + contentDisplayer.setBounds(ins.top, ins.left, width, + parent.getHeight() - (d.height + ins.top + ins.bottom)); + + c.setBounds(ins.left, parent.getHeight() - (d.height + ins.top + ins.bottom), + width, d.height); } else if (orientation == TabDisplayer.ORIENTATION_EAST) { - contentDisplayer.setBounds (ins.left, ins.top, width - d.width, - height); - - c.setBounds (parent.getWidth() - (ins.right + d.width), ins.top, - d.width, height); - + contentDisplayer.setBounds(ins.left, ins.top, width - d.width, + height); + + c.setBounds(parent.getWidth() - (ins.right + d.width), ins.top, + d.width, height); + } else if (orientation == TabDisplayer.ORIENTATION_WEST) { - c.setBounds (ins.left, ins.top, d.width, height); - - contentDisplayer.setBounds (ins.left + d.width, ins.top, - width - d.width, height); - + c.setBounds(ins.left, ins.top, d.width, height); + + contentDisplayer.setBounds(ins.left + d.width, ins.top, + width - d.width, height); + } else { - throw new IllegalArgumentException ("Unknown orientation: " + orientation); + throw new IllegalArgumentException("Unknown orientation: " + orientation); } } - + + @Override public Dimension minimumLayoutSize(Container parent) { JComponent c = tabDisplayer; - - Object orientation = c.getClientProperty ( - TabDisplayer.PROP_ORIENTATION); - + + Object orientation = c.getClientProperty( + TabDisplayer.PROP_ORIENTATION); + Dimension tabSize = tabDisplayer.getPreferredSize(); Insets ins = container.getInsets(); - + Dimension result = new Dimension(); - + Dimension contentSize = contentDisplayer.getPreferredSize(); if (tabDisplayer.getSelectionModel().getSelectedIndex() == -1) { contentSize.width = 0; contentSize.height = 0; } - + if (orientation == TabDisplayer.ORIENTATION_NORTH || orientation == TabDisplayer.ORIENTATION_SOUTH) { result.height = ins.top + ins.bottom + contentSize.height + tabSize.height; - result.width = ins.left + ins.right + Math.max (contentSize.width, tabSize.width); + result.width = ins.left + ins.right + Math.max(contentSize.width, tabSize.width); } else { result.width = ins.left + ins.right + contentSize.width + tabSize.width; - result.height = ins.top + ins.bottom + Math.max (contentSize.height, tabSize.height); + result.height = ins.top + ins.bottom + Math.max(contentSize.height, tabSize.height); } return result; } - + + @Override public Dimension preferredLayoutSize(Container parent) { return minimumLayoutSize(parent); } - + + @Override public void removeLayoutComponent(Component comp) { //do nothing } } - - /** A FxProvider which simply calls finish() from its start - * method, providing no effects whatsoever */ + + /** + * A FxProvider which simply calls finish() from its start method, providing + * no effects whatsoever + */ private final class NoOpFxProvider extends FxProvider { - + + @Override public void cleanup() { //Do nothing } - + + @Override protected void doFinish() { - showComponent (comp); - + showComponent(comp); + } - + + @Override protected void doStart() { finish(); } } - + private final class ImageSlideFxProvider extends FxProvider implements ActionListener { + private Timer timer = null; private Component prevGlassPane = null; private Dimension d = null; - + + @Override protected void doStart() { if (timer == null) { - timer = new Timer (TIMER, this); + timer = new Timer(TIMER, this); timer.setRepeats(true); } @@ -1413,17 +1540,17 @@ initSize(); img = createImageOfComponent(); - ImageScalingGlassPane cp = getCustomGlassPane(); - root.setGlassPane (cp); - cp.setIncrement (0.1f); - cp.setBounds (root.getBounds()); + root.setGlassPane(cp); + cp.setIncrement(0.1f); + cp.setBounds(root.getBounds()); cp.setVisible(true); cp.revalidate(); - timer.start(); + timer.start(); } - + + @Override public void cleanup() { timer.stop(); root.setGlassPane(prevGlassPane); @@ -1433,23 +1560,23 @@ } img = null; } - + + @Override protected void doFinish() { - showComponent (comp); + showComponent(comp); } - + private void initSize() { d = comp.getPreferredSize(); - + Dimension d2 = contentDisplayer.getSize(); - - d.width = Math.max (d2.width, d.width); - d.height = Math.max (d2.height, d.height); - - boolean flip = orientation == TabDisplayer.ORIENTATION_EAST || - orientation == TabDisplayer.ORIENTATION_WEST; - + d.width = Math.max(d2.width, d.width); + d.height = Math.max(d2.height, d.height); + + boolean flip = orientation == TabDisplayer.ORIENTATION_EAST + || orientation == TabDisplayer.ORIENTATION_WEST; + if (d.width == 0 || d.height == 0) { if (flip) { d.width = root.getWidth(); @@ -1460,14 +1587,15 @@ } } else { if (flip) { - d.height = Math.max (d.height, tabDisplayer.getHeight()); + d.height = Math.max(d.height, tabDisplayer.getHeight()); } else { - d.width = Math.max (d.width, tabDisplayer.getWidth()); + d.width = Math.max(d.width, tabDisplayer.getWidth()); } } - } + } private BufferedImage img = null; + private BufferedImage createImageOfComponent() { if (USE_SWINGPAINTING) { return null; @@ -1478,30 +1606,32 @@ finish(); } - BufferedImage img = - GraphicsEnvironment.getLocalGraphicsEnvironment(). + BufferedImage img + = GraphicsEnvironment.getLocalGraphicsEnvironment(). getDefaultScreenDevice().getDefaultConfiguration(). createCompatibleImage(d.width, d.height); - + Graphics2D g2d = img.createGraphics(); JComponent c = tabDisplayer; - - c.setBounds (0, 0, d.width, d.height); - comp.paint (g2d); + + c.setBounds(0, 0, d.width, d.height); + comp.paint(g2d); return img; - } - + } + + @Override public void actionPerformed(java.awt.event.ActionEvent e) { float inc = customGlassPane.getIncrement(); if (inc >= 1.0f) { finish(); } else { - customGlassPane.setIncrement (inc + INCREMENT); + customGlassPane.setIncrement(inc + INCREMENT); } } - + private ImageScalingGlassPane customGlassPane = null; + private ImageScalingGlassPane getCustomGlassPane() { if (customGlassPane == null) { customGlassPane = new ImageScalingGlassPane(); @@ -1509,47 +1639,48 @@ } return customGlassPane; } - + private class ImageScalingGlassPane extends JPanel { + private float inc = 0f; private Rectangle rect = new Rectangle(); private Rectangle r2 = new Rectangle(); private boolean changed = true; - - private void setIncrement (float inc) { + + private void setIncrement(float inc) { this.inc = inc; changed = true; if (isShowing()) { Rectangle r = getImageBounds(); if (SYNCHRONOUS_PAINTING) { - paintImmediately (r.x, r.y, r.width, r.height); + paintImmediately(r.x, r.y, r.width, r.height); } else { repaint(r.x, r.y, r.width, r.height); } } } - - private float getIncrement () { + + private float getIncrement() { return inc; } - + private Rectangle getImageBounds() { if (!changed) { return rect; } Component c = tabDisplayer; - r2.setBounds (0, 0, c.getWidth(), c.getHeight()); - - Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, - this); - + r2.setBounds(0, 0, c.getWidth(), c.getHeight()); + + Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, + this); + if (orientation == TabDisplayer.ORIENTATION_WEST) { rect.x = dispBounds.x + dispBounds.width; rect.y = dispBounds.y; - rect.width = Math.round (inc * d.width); + rect.width = Math.round(inc * d.width); rect.height = dispBounds.height; } else if (orientation == TabDisplayer.ORIENTATION_EAST) { - rect.width = Math.round (inc * d.width); + rect.width = Math.round(inc * d.width); rect.height = dispBounds.height; rect.x = dispBounds.x - rect.width; rect.y = dispBounds.y; @@ -1567,7 +1698,8 @@ changed = false; return rect; } - + + @Override public void paint(Graphics g) { try { if (USE_SWINGPAINTING) { @@ -1577,16 +1709,16 @@ Composite comp = null; if (true) { comp = g2d.getComposite(); - g2d.setComposite (AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Math.min(0.99f, inc))); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Math.min(0.99f, inc))); } Rectangle r = getImageBounds(); if (NO_SCALE) { AffineTransform at = AffineTransform.getTranslateInstance(r.x, r.y); g2d.drawRenderedImage(img, at); } else { - g2d.drawImage (img, r.x, r.y, r.x + r.width, - r.y + r.height, 0, 0, d.width, d.height, - getBackground(), null); + g2d.drawImage(img, r.x, r.y, r.x + r.width, + r.y + r.height, 0, 0, d.width, d.height, + getBackground(), null); } if (comp != null) { g2d.setComposite(comp); @@ -1600,16 +1732,17 @@ } } } - private final class LiveComponentSlideFxProvider extends FxProvider implements ActionListener { + private Timer timer = null; private Component prevGlassPane = null; private Dimension d = null; + @Override protected void doStart() { if (timer == null) { - timer = new Timer (TIMER, this); + timer = new Timer(TIMER, this); timer.setRepeats(true); } @@ -1622,25 +1755,25 @@ initSize(); LiveComponentResizingGlassPane cp = getCustomGlassPane(); - root.setGlassPane (cp); - cp.setIncrement (0.1f); - cp.setBounds (root.getBounds()); + root.setGlassPane(cp); + cp.setIncrement(0.1f); + cp.setBounds(root.getBounds()); cp.setVisible(true); cp.revalidate(); timer.start(); } - + private void initSize() { d = comp.getPreferredSize(); - + Dimension d2 = contentDisplayer.getSize(); - - d.width = Math.max (d2.width, d.width); - d.height = Math.max (d2.height, d.height); - - boolean flip = orientation == TabDisplayer.ORIENTATION_EAST || - orientation == TabDisplayer.ORIENTATION_WEST; - + + d.width = Math.max(d2.width, d.width); + d.height = Math.max(d2.height, d.height); + + boolean flip = orientation == TabDisplayer.ORIENTATION_EAST + || orientation == TabDisplayer.ORIENTATION_WEST; + if (d.width == 0 || d.height == 0) { if (flip) { d.width = root.getWidth(); @@ -1651,34 +1784,38 @@ } } else { if (flip) { - d.height = Math.max (d.height, tabDisplayer.getHeight()); + d.height = Math.max(d.height, tabDisplayer.getHeight()); } else { - d.width = Math.max (d.width, tabDisplayer.getWidth()); + d.width = Math.max(d.width, tabDisplayer.getWidth()); } } } - + + @Override public void cleanup() { timer.stop(); root.setGlassPane(prevGlassPane); prevGlassPane.setVisible(false); customGlassPane.remove(comp); } - + + @Override protected void doFinish() { - showComponent (comp); + showComponent(comp); } - + + @Override public void actionPerformed(java.awt.event.ActionEvent e) { float inc = customGlassPane.getIncrement(); if (inc >= 1.0f) { finish(); } else { - customGlassPane.setIncrement (inc + INCREMENT); + customGlassPane.setIncrement(inc + INCREMENT); } } - + private LiveComponentResizingGlassPane customGlassPane = null; + private LiveComponentResizingGlassPane getCustomGlassPane() { if (customGlassPane == null) { customGlassPane = new LiveComponentResizingGlassPane(); @@ -1686,14 +1823,15 @@ } return customGlassPane; } - + private class LiveComponentResizingGlassPane extends JPanel { + private float inc = 0f; private Rectangle rect = new Rectangle(); private Rectangle r2 = new Rectangle(); private boolean changed = true; - - private void setIncrement (float inc) { + + private void setIncrement(float inc) { this.inc = inc; changed = true; if (isShowing()) { @@ -1704,33 +1842,34 @@ } doLayout(); } - + + @Override public void doLayout() { Rectangle r = getImageBounds(); - comp.setBounds (r.x, r.y, r.width, r.height); + comp.setBounds(r.x, r.y, r.width, r.height); } - - private float getIncrement () { + + private float getIncrement() { return inc; } - + private Rectangle getImageBounds() { if (!changed) { return rect; } Component c = tabDisplayer; - r2.setBounds (0, 0, c.getWidth(), c.getHeight()); - - Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, - this); - + r2.setBounds(0, 0, c.getWidth(), c.getHeight()); + + Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, + this); + if (orientation == TabDisplayer.ORIENTATION_WEST) { rect.x = dispBounds.x + dispBounds.width; rect.y = dispBounds.y; - rect.width = Math.round (inc * d.width); + rect.width = Math.round(inc * d.width); rect.height = dispBounds.height; } else if (orientation == TabDisplayer.ORIENTATION_EAST) { - rect.width = Math.round (inc * d.width); + rect.width = Math.round(inc * d.width); rect.height = dispBounds.height; rect.x = dispBounds.x - rect.width; rect.y = dispBounds.y; @@ -1749,50 +1888,63 @@ return rect; } } - } - + } + //*** A bunch of options for testing - - /** Sysprop to turn off all sliding effects */ - static final boolean NO_EFFECTS = Boolean.getBoolean ("nb.tabcontrol.no.fx"); //NOI18N - /** Sysprop to turn off scaling of the slide image */ - static final boolean NO_SCALE = Boolean.getBoolean ("nb.tabcontrol.fx.no.scaling"); //NOI18N - /** Sysprop to turn use SwingUtilities.paintComponent() instead of an image buffer for sliding effects */ - static final boolean USE_SWINGPAINTING = Boolean.getBoolean ("nb.tabcontrol.fx.swingpainting"); //NOI18N - /** Sysprop to turn add the component being scaled to the glasspane and alter its size on a - * timer to accomplish growing the component */ - static final boolean ADD_TO_GLASSPANE = Boolean.getBoolean ("nb.tabcontrol.fx.use.resizing"); //NOI18N - /** For those who really love the sliding effect and want to see it on all - * tab controls of all types */ - static final boolean EFFECTS_EVERYWHERE = Boolean.getBoolean ("nb.tabcontrol.fx.everywhere") || - Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N - - /** Also have the scaled image be partially transparent as it's drawn */ - static final boolean USE_ALPHA = Boolean.getBoolean ("nb.tabcontrol.fx.use.alpha") || - Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N - - static boolean SYNCHRONOUS_PAINTING = Boolean.getBoolean ("nb.tabcontrol.fx.synchronous"); //NOI18N - + /** + * Sysprop to turn off all sliding effects + */ + static final boolean NO_EFFECTS = Boolean.getBoolean("nb.tabcontrol.no.fx"); //NOI18N + /** + * Sysprop to turn off scaling of the slide image + */ + static final boolean NO_SCALE = Boolean.getBoolean("nb.tabcontrol.fx.no.scaling"); //NOI18N + /** + * Sysprop to turn use SwingUtilities.paintComponent() instead of an image + * buffer for sliding effects + */ + static final boolean USE_SWINGPAINTING = Boolean.getBoolean("nb.tabcontrol.fx.swingpainting"); //NOI18N + /** + * Sysprop to turn add the component being scaled to the glasspane and alter + * its size on a timer to accomplish growing the component + */ + static final boolean ADD_TO_GLASSPANE = Boolean.getBoolean("nb.tabcontrol.fx.use.resizing"); //NOI18N + /** + * For those who really love the sliding effect and want to + * see it on all tab controls of all types + */ + static final boolean EFFECTS_EVERYWHERE = Boolean.getBoolean("nb.tabcontrol.fx.everywhere") + || Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N + + /** + * Also have the scaled image be partially transparent as it's drawn + */ + static final boolean USE_ALPHA = Boolean.getBoolean("nb.tabcontrol.fx.use.alpha") + || Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N + + static boolean SYNCHRONOUS_PAINTING = Boolean.getBoolean("nb.tabcontrol.fx.synchronous"); //NOI18N + static float INCREMENT = 0.07f; - + static int TIMER = 25; + static { boolean gratuitous = Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N - String s = System.getProperty ("nb.tabcontrol.fx.increment"); //NOI18N + String s = System.getProperty("nb.tabcontrol.fx.increment"); //NOI18N if (s != null) { try { INCREMENT = Float.parseFloat(s); } catch (Exception e) { - System.err.println("Bad float value specified: \"" + s +"\""); //NOI18N + System.err.println("Bad float value specified: \"" + s + "\""); //NOI18N } } else if (gratuitous) { INCREMENT = 0.02f; } - - s = System.getProperty ("nb.tabcontrol.fx.timer"); //NOI18N + + s = System.getProperty("nb.tabcontrol.fx.timer"); //NOI18N if (s != null) { try { - TIMER = Integer.parseInt (s); + TIMER = Integer.parseInt(s); } catch (Exception e) { System.err.println("Bad integer value specified: \"" + s + "\""); //NOI18N } @@ -1803,62 +1955,70 @@ SYNCHRONOUS_PAINTING = true; } } - + private static final class ForwardingMouseListener implements MouseListener { + private final Container c; - public ForwardingMouseListener (Container c) { + + public ForwardingMouseListener(Container c) { this.c = c; } - public void mousePressed (MouseEvent me) { - forward (me); + + @Override + public void mousePressed(MouseEvent me) { + forward(me); } - - public void mouseReleased (MouseEvent me) { - forward (me); + + @Override + public void mouseReleased(MouseEvent me) { + forward(me); } - - public void mouseClicked (MouseEvent me) { - forward (me); + + @Override + public void mouseClicked(MouseEvent me) { + forward(me); } - - public void mouseEntered (MouseEvent me) { - forward (me); + + @Override + public void mouseEntered(MouseEvent me) { + forward(me); } - - public void mouseExited (MouseEvent me) { - forward (me); + + @Override + public void mouseExited(MouseEvent me) { + forward(me); } - - private void forward (MouseEvent me) { + + private void forward(MouseEvent me) { MouseListener[] ml = c.getMouseListeners(); if (ml.length == 0 || me.isConsumed()) { return; } MouseEvent me2 = SwingUtilities.convertMouseEvent( - (Component) me.getSource(), me, c); - - for (int i=0; i < ml.length; i++) { + (Component) me.getSource(), me, c); + + for (int i = 0; i < ml.length; i++) { switch (me2.getID()) { - case MouseEvent.MOUSE_ENTERED : + case MouseEvent.MOUSE_ENTERED: ml[i].mouseEntered(me2); break; - case MouseEvent.MOUSE_EXITED : + case MouseEvent.MOUSE_EXITED: ml[i].mouseExited(me2); break; - case MouseEvent.MOUSE_PRESSED : + case MouseEvent.MOUSE_PRESSED: ml[i].mousePressed(me2); break; - case MouseEvent.MOUSE_RELEASED : + case MouseEvent.MOUSE_RELEASED: ml[i].mouseReleased(me2); break; - case MouseEvent.MOUSE_CLICKED : + case MouseEvent.MOUSE_CLICKED: ml[i].mouseClicked(me2); break; - default : + default: assert false; } } } - + } } diff --git a/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/StackLayout.java b/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/StackLayout.java --- a/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/StackLayout.java +++ b/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/StackLayout.java @@ -56,8 +56,8 @@ * * @author Dafe Simonek */ -class StackLayout implements LayoutManager { - +public class StackLayout implements LayoutManager { + // #100486 - hold visibleComp weakly, because removeLayoutComponent may not // be called and then visibleComp is not freed. See StackLayoutTest for details. /** @@ -75,6 +75,9 @@ Component comp = getVisibleComponent(); if (comp != c) { if (!parent.isAncestorOf(c) && c != null) { + if (c.getParent() != null) { + c.getParent().remove(c); + } parent.add(c); } synchronized (parent.getTreeLock()) { @@ -107,6 +110,7 @@ * ********** Implementation of LayoutManager interface ********* */ + @Override public void addLayoutComponent(String name, Component comp) { synchronized (comp.getTreeLock()) { comp.setVisible(false); @@ -136,6 +140,7 @@ } }*/ + @Override public void removeLayoutComponent(Component comp) { synchronized (comp.getTreeLock()) { if (comp == getVisibleComponent()) { @@ -147,6 +152,7 @@ } } + @Override public void layoutContainer(Container parent) { Component visibleComp = getVisibleComponent(); if (visibleComp != null) { @@ -177,5 +183,4 @@ private static Dimension getEmptySize() { return new Dimension(50, 50); } - }