diff --git a/src/share/classes/javax/swing/JComponent.java b/src/share/classes/javax/swing/JComponent.java index ae3bddf11826a64be493f299ceeabc63af3925de..f94a797ae6c695113bf43e54a8a88d2fb1bf2d7b 100644 --- a/src/share/classes/javax/swing/JComponent.java +++ b/src/share/classes/javax/swing/JComponent.java @@ -4787,6 +4787,17 @@ public abstract class JComponent extends Container implements Serializable, * @see RepaintManager#addDirtyRegion */ public void repaint(long tm, int x, int y, int width, int height) { + Container p = this; + while ((p = p.getParent()) instanceof JComponent) { + JComponent jp = (JComponent) p; + if (jp.isPaintingOrigin()) { + Rectangle rectangle = SwingUtilities.convertRectangle( + this, new Rectangle(x, y, width, height), jp); + jp.repaint(tm, + rectangle.x, rectangle.y, rectangle.width, rectangle.height); + return; + } + } RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height); } diff --git a/src/share/classes/javax/swing/JLayer.java b/src/share/classes/javax/swing/JLayer.java index dd7874c3e70ede40828d8f339a1293a95f3a3485..eab0bf4ab2f9171fff5fd23c06e4f425b207311c 100644 --- a/src/share/classes/javax/swing/JLayer.java +++ b/src/share/classes/javax/swing/JLayer.java @@ -25,17 +25,17 @@ package javax.swing; +import sun.awt.AWTAccessor; + import javax.swing.plaf.LayerUI; +import javax.swing.border.Border; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; import java.security.AccessController; import java.security.PrivilegedAction; @@ -156,8 +156,6 @@ public final class JLayer private LayerUI layerUI; private JPanel glassPane; private boolean isPainting; - private static final DefaultLayerLayout sharedLayoutInstance = - new DefaultLayerLayout(); private long eventMask; private static final LayerEventController eventController = @@ -165,7 +163,7 @@ public final class JLayer /** * Creates a new {@code JLayer} object with a {@code null} view component - * and {@code null} {@link javax.swing.plaf.LayerUI}. + * and default {@link javax.swing.plaf.LayerUI}. * * @see #setView * @see #setUI @@ -176,14 +174,14 @@ public final class JLayer /** * Creates a new {@code JLayer} object - * with {@code null} {@link javax.swing.plaf.LayerUI}. + * with default {@link javax.swing.plaf.LayerUI}. * * @param view the component to be decorated by this {@code JLayer} * * @see #setUI */ public JLayer(V view) { - this(view, null); + this(view, new LayerUI()); } /** @@ -195,7 +193,6 @@ public final class JLayer * to be used by this {@code JLayer} */ public JLayer(V view, LayerUI ui) { - setLayout(sharedLayoutInstance); setGlassPane(createGlassPane()); setView(view); setUI(ui); @@ -279,10 +276,15 @@ public final class JLayer */ public void setGlassPane(JPanel glassPane) { Component oldGlassPane = getGlassPane(); + boolean isGlassPaneVisible = false; if (oldGlassPane != null) { + isGlassPaneVisible = oldGlassPane.isVisible(); super.remove(oldGlassPane); } if (glassPane != null) { + AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane, + new Rectangle()); + glassPane.setVisible(isGlassPaneVisible); super.addImpl(glassPane, null, 0); } this.glassPane = glassPane; @@ -302,6 +304,40 @@ public final class JLayer return new DefaultLayerGlassPane(); } + /** + * Sets the layout manager for this container. This method is + * overridden to prevent the layout manager from being set. + *

Note: If {@code mgr} is non-{@code null}, this + * method will throw an exception as layout managers are not supported on + * a {@code JLayer}. + * + * @param mgr the specified layout manager + * @exception IllegalArgumentException this method is not supported + */ + public void setLayout(LayoutManager mgr) { + if (mgr != null) { + throw new IllegalArgumentException("JLayer.setLayout() not supported"); + } + } + + /** + * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry + * of this component from becoming complex enough to inhibit + * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, + * add it to a {@code JPanel} that has a border. + *

Note: If {@code border} is non-{@code null}, this + * method will throw an exception as borders are not supported on + * a {@code JLayer}. + * + * @param border the {@code Border} to set + * @exception IllegalArgumentException this method is not supported + */ + public void setBorder(Border border) { + if (border != null) { + throw new IllegalArgumentException("JLayer.setBorder() not supported"); + } + } + /** * This method is not supported by {@code JLayer} * and always throws {@code UnsupportedOperationException} @@ -340,6 +376,32 @@ public final class JLayer setGlassPane(null); } + /** + * Always returns {@code true} to cause painting to originate from {@code JLayer}, + * or one of its ancestors. + * + * @return true + * @see JComponent#isPaintingOrigin() + */ + boolean isPaintingOrigin() { + return true; + } + + /** + * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + */ + public void repaint(long tm, int x, int y, int width, int height) { + if (getUI() != null) { + getUI().repaint(tm, x, y, width, height, this); + } + } + /** * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object. * @@ -364,14 +426,18 @@ public final class JLayer } /** - * To enable the correct painting of the {@code glassPane} and view component, - * the {@code JLayer} overrides the default implementation of - * this method to return {@code false} when the {@code glassPane} is visible. - * - * @return false if {@code JLayer}'s {@code glassPane} is visible + * The {@code JLayer} overrides the default implementation of + * this method (in {@code JComponent}) to return {@code false}. + * This ensures + * that the drawing machinery will call the {@code JLayer}'s + * {@code paint} + * implementation rather than messaging the {@code JLayer}'s + * children directly. + * + * @return false */ public boolean isOptimizedDrawingEnabled() { - return glassPane == null || !glassPane.isVisible(); + return false; } /** @@ -461,17 +527,16 @@ public final class JLayer /** * Returns the preferred size of the viewport for a view component. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the preferred size of the viewport for a view component * * @see Scrollable - * @see LayerUI#getPreferredScrollableViewportSize(JLayer) */ public Dimension getPreferredScrollableViewportSize() { - if (getUI() != null) { - return getUI().getPreferredScrollableViewportSize(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getPreferredScrollableViewportSize(); } return getPreferredSize(); } @@ -481,18 +546,17 @@ public final class JLayer * that display logical rows or columns in order to completely expose * one block of rows or columns, depending on the value of orientation. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the "block" increment for scrolling in the specified direction * * @see Scrollable - * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int) */ public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableBlockIncrement(this, visibleRect, + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect, orientation, direction); } return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : @@ -504,17 +568,16 @@ public final class JLayer * determine the height of the layer, unless the preferred height * of the layer is smaller than the height of the viewport. *

- * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the height of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportHeight(JLayer) */ public boolean getScrollableTracksViewportHeight() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportHeight(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportHeight(); } return false; } @@ -524,17 +587,16 @@ public final class JLayer * determine the width of the layer, unless the preferred width * of the layer is smaller than the width of the viewport. *

- * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the width of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) */ public boolean getScrollableTracksViewportWidth() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportWidth(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportWidth(); } return false; } @@ -549,20 +611,19 @@ public final class JLayer * Scrolling containers, like {@code JScrollPane}, will use this method * each time the user requests a unit scroll. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return The "unit" increment for scrolling in the specified direction. * This value should always be positive. * * @see Scrollable - * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int) */ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableUnitIncrement( - this, visibleRect, orientation, direction); + if (getView() instanceof Scrollable) { + return ((Scrollable) getView()).getScrollableUnitIncrement( + visibleRect, orientation, direction); } return 1; } @@ -594,6 +655,16 @@ public final class JLayer eventController.updateAWTEventListener(eventMask, 0); } + /** + * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method, + * if {@code LayerUI} is set. + */ + public void doLayout() { + if (getUI() != null) { + getUI().doLayout(this); + } + } + /** * static AWTEventListener to be shared with all AbstractLayerUIs */ @@ -625,8 +696,8 @@ public final class JLayer JLayer l = (JLayer) component; LayerUI ui = l.getUI(); if (ui != null && - isEventEnabled(l.getLayerEventMask(), - event.getID())) { + isEventEnabled(l.getLayerEventMask(), event.getID()) && + (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) { ui.eventDispatched(event, l); } } @@ -758,82 +829,4 @@ public final class JLayer return super.contains(x, y); } } - - /** - * The default layout manager for the {@link javax.swing.JLayer}.
- * It places the glassPane on top of the view component - * and makes it the same size as {@code JLayer}, - * it also makes the view component the same size but minus layer's insets
- */ - private static class DefaultLayerLayout implements LayoutManager, Serializable { - /** - * {@inheritDoc} - */ - public void layoutContainer(Container parent) { - JLayer layer = (JLayer) parent; - Component view = layer.getView(); - Component glassPane = layer.getGlassPane(); - if (view != null) { - Insets insets = layer.getInsets(); - view.setLocation(insets.left, insets.top); - view.setSize(layer.getWidth() - insets.left - insets.right, - layer.getHeight() - insets.top - insets.bottom); - } - if (glassPane != null) { - glassPane.setLocation(0, 0); - glassPane.setSize(layer.getWidth(), layer.getHeight()); - } - } - - /** - * {@inheritDoc} - */ - public Dimension minimumLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getMinimumSize(); - ret.width += size.width; - ret.height += size.height; - } - if (ret.width == 0 || ret.height == 0) { - ret.width = ret.height = 4; - } - return ret; - } - - /** - * {@inheritDoc} - */ - public Dimension preferredLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getPreferredSize(); - if (size.width > 0 && size.height > 0) { - ret.width += size.width; - ret.height += size.height; - } - } - return ret; - } - - /** - * {@inheritDoc} - */ - public void addLayoutComponent(String name, Component comp) { - } - - /** - * {@inheritDoc} - */ - public void removeLayoutComponent(Component comp) { - } - } } diff --git a/src/share/classes/javax/swing/plaf/LayerUI.java b/src/share/classes/javax/swing/plaf/LayerUI.java index 2cfa8e185ccceb33ecf94ab803b2a2ef27d2be69..1fb757313a4db0b1a8d31fc084b30041f1e11ff9 100644 --- a/src/share/classes/javax/swing/plaf/LayerUI.java +++ b/src/share/classes/javax/swing/plaf/LayerUI.java @@ -600,136 +600,124 @@ public class LayerUI } /** - * Returns the preferred size of the viewport for a view component. + * If the {@code JLayer}'s view component is not {@code null}, + * this calls the view's {@code getBaseline()} method. + * Otherwise, the default implementation is called. * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return the preferred size of the viewport for a view component - * @see Scrollable#getPreferredScrollableViewportSize() + * @param c {@code JLayer} to return baseline resize behavior for + * @param width the width to get the baseline for + * @param height the height to get the baseline for + * @return baseline or a value < 0 indicating there is no reasonable + * baseline */ - public Dimension getPreferredScrollableViewportSize(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getPreferredScrollableViewportSize(); + public int getBaseline(JComponent c, int width, int height) { + JLayer l = (JLayer) c; + if (l.getView() != null) { + return l.getView().getBaseline(width, height); } - return l.getPreferredSize(); - } + return super.getBaseline(c, width, height); + } /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one block of rows or columns, depending on the value of orientation. + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getBaselineResizeBehavior()} method. + * Otherwise, the default implementation is called. * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return the "block" increment for scrolling in the specified direction - * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int) + * @param c {@code JLayer} to return baseline resize behavior for + * @return an enum indicating how the baseline changes as the component + * size changes */ - public int getScrollableBlockIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableBlockIncrement( - visibleRect,orientation, direction); + public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) { + JLayer l = (JLayer) c; + if (l.getView() != null) { + return l.getView().getBaselineResizeBehavior(); } - return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : - visibleRect.width; + return super.getBaselineResizeBehavior(c); } /** - * Returns {@code false} to indicate that the height of the viewport does not - * determine the height of the layer, unless the preferred height - * of the layer is smaller than the height of the viewport. + * Causes the passed instance of {@code JLayer} to lay out its components. * * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the height of the viewport - * @see Scrollable#getScrollableTracksViewportHeight() */ - public boolean getScrollableTracksViewportHeight(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportHeight(); + public void doLayout(JLayer l) { + Component view = l.getView(); + if (view != null) { + view.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + Component glassPane = l.getGlassPane(); + if (glassPane != null) { + glassPane.setBounds(0, 0, l.getWidth(), l.getHeight()); } - return false; } /** - * Returns {@code false} to indicate that the width of the viewport does not - * determine the width of the layer, unless the preferred width - * of the layer is smaller than the width of the viewport. + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getPreferredSize()} method. + * Otherwise, the default implementation is used. * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the width of the viewport - * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) + * @param c {@code JLayer} to return preferred size for + * @return preferred size for the passed {@code JLayer} */ - public boolean getScrollableTracksViewportWidth(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportWidth(); + public Dimension getPreferredSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getPreferredSize(); } - return false; + return super.getPreferredSize(c); } /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one new row or column, depending on the value of orientation. - * Ideally, components should handle a partially exposed row or column - * by returning the distance required to completely expose the item. - *

- * Scrolling containers, like JScrollPane, will use this method - * each time the user requests a unit scroll. + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMinimalSize()} method. + * Otherwise, the default implementation is used. * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return The "unit" increment for scrolling in the specified direction. - * This value should always be positive. - * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int) + * @param c {@code JLayer} to return preferred size for + * @return minimal size for the passed {@code JLayer} */ - public int getScrollableUnitIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableUnitIncrement( - visibleRect, orientation, direction); + public Dimension getMinimumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMinimumSize(); } - return 1; + return super.getMinimumSize(c); } /** * If the {@code JLayer}'s view component is not {@code null}, - * this calls the view's {@code getBaseline()} method. - * Otherwise, the default implementation is called. + * this returns the result of the view's {@code getMaximumSize()} method. + * Otherwise, the default implementation is used. * - * @param c {@code JLayer} to return baseline resize behavior for - * @param width the width to get the baseline for - * @param height the height to get the baseline for - * @return baseline or a value < 0 indicating there is no reasonable - * baseline + * @param c {@code JLayer} to return preferred size for + * @return maximun size for the passed {@code JLayer} */ - public int getBaseline(JComponent c, int width, int height) { + public Dimension getMaximumSize(JComponent c) { JLayer l = (JLayer) c; - if (l.getView() != null) { - return l.getView().getBaseline(width, height); + Component view = l.getView(); + if (view != null) { + return view.getMaximumSize(); } - return super.getBaseline(c, width, height); - } + return super.getMaximumSize(c); + } /** - * If the {@code JLayer}'s view component is not {@code null}, - * this calls the view's {@code getBaselineResizeBehavior()} method. - * Otherwise, the default implementation is called. - * - * @param c {@code JLayer} to return baseline resize behavior for - * @return an enum indicating how the baseline changes as the component - * size changes + * Adds the specified region to the dirty region list if the component + * is showing. The component will be repainted after all of the + * currently pending events have been dispatched. + *

+ * This method is to be overridden when the dirty region needs to be changed. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + * @see java.awt.Component#isShowing + * @see RepaintManager#addDirtyRegion */ - public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) { - JLayer l = (JLayer) c; - if (l.getView() != null) { - return l.getView().getBaselineResizeBehavior(); - } - return super.getBaselineResizeBehavior(c); + public void repaint(long tm, int x, int y, int width, int height, JLayer l) { + RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height); } }