This implements support for JScrollPane.setViewportBorder(). Interestingly, this _doesn't_ simply set the border on the viewport (you can still set another border on this). Instead, I implemented this to paint this border in BasicScrollPaneUI.paint() and consider this specially in the ScrollPaneLayout.

2006-08-13  Roman Kennke  <[EMAIL PROTECTED]>

        PR 28135
        * javax/swing/ScrollPaneLayout.java
        (layoutContainer): Consider the viewportBorder of the
        JScrollPane.
        (minimumLayoutSize): Consider the viewportBorder of the
        JScrollPane.
        (preferredLayoutSize): Consider the viewportBorder of the
        JScrollPane.
        * javax/swing/plaf/basic/BasicScrollPaneUI.java
        (installDefaults): Also install viewportBorder if specified.
        (paint): Paint viewportBorder if present.
        (uninstallDefaults): Uninstall viewportBorder if appropriate.
        Don't nullify foreground, background and font. Uninstall
        border via LookAndFeel helper method to avoid uninstall
        user set border.

/Roman
Index: javax/swing/ScrollPaneLayout.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/ScrollPaneLayout.java,v
retrieving revision 1.25
diff -u -1 -2 -r1.25 ScrollPaneLayout.java
--- javax/swing/ScrollPaneLayout.java	1 Jul 2006 21:33:16 -0000	1.25
+++ javax/swing/ScrollPaneLayout.java	13 Aug 2006 22:14:27 -0000
@@ -37,24 +37,26 @@
 
 
 package javax.swing;
 
 import java.awt.Component;
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Insets;
 import java.awt.LayoutManager;
 import java.awt.Rectangle;
 import java.io.Serializable;
 
+import javax.swing.border.Border;
+
 /**
  * ScrollPaneLayout
  * @author	Andrew Selkirk
  * @version	1.0
  */
 public class ScrollPaneLayout
   implements LayoutManager, ScrollPaneConstants, Serializable
 {
   private static final long serialVersionUID = -4480022884523193743L;
 
   public static class UIResource extends ScrollPaneLayout 
     implements javax.swing.plaf.UIResource
@@ -268,47 +270,66 @@
     // is larger than the viewport's preferred width
     if (hsb != null && viewSize.width > viewportSize.width)
       height += hsb.getPreferredSize().height;
 
     // vertical scrollbar needed if the view's preferred height
     // is larger than the viewport's preferred height
     if (vsb != null && viewSize.height > viewportSize.height)
       width += vsb.getPreferredSize().width;
     if (rowHead != null && rowHead.isVisible())
       width += rowHead.getPreferredSize().width;
     if (colHead != null && colHead.isVisible())
       height += colHead.getPreferredSize().height;
+
+    // Add insets of viewportBorder if present.
+    Border vpBorder = sc.getViewportBorder();
+    if (vpBorder != null)
+      {
+        Insets i = vpBorder.getBorderInsets(sc);
+        width += i.left + i.right;
+        height += i.top + i.bottom;
+      }
+
     Insets i = sc.getInsets();
     return new Dimension(width + i.left + i.right,
                          height + i.left + i.right);
   }
 
   public Dimension minimumLayoutSize(Container parent)
   {
     // Sun's implementation simply throws a ClassCastException if
     // parent is no JScrollPane, so do we.
     JScrollPane sc = (JScrollPane) parent;
     Insets i = sc.getInsets();
     Dimension viewportMinSize = sc.getViewport().getMinimumSize();
 
     int width = i.left + i.right + viewportMinSize.width;
     if (sc.getVerticalScrollBarPolicy()
         != JScrollPane.VERTICAL_SCROLLBAR_NEVER)
       width += sc.getVerticalScrollBar().getMinimumSize().width;
 
     int height = i.top + i.bottom + viewportMinSize.height;
     if (sc.getHorizontalScrollBarPolicy()
         != JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
       height += sc.getHorizontalScrollBar().getMinimumSize().height;
 
+    // Add insets of viewportBorder if present.
+    Border vpBorder = sc.getViewportBorder();
+    if (vpBorder != null)
+      {
+        i = vpBorder.getBorderInsets(sc);
+        width += i.left + i.right;
+        height += i.top + i.bottom;
+      }
+
     return new Dimension(width, height);
   }
 
   /**
    *
    *     +----+--------------------+----+ y1
    *     | c1 |   column header    | c2 |
    *     +----+--------------------+----+ y2
    *     | r  |                    | v  |
    *     | o  |                    |    |
    *     | w  |                    | s  |
    *     |    |                    | r  |
@@ -333,24 +354,33 @@
     Component view = viewport.getView();
     
     // If there is no view in the viewport, there is no work to be done.
     if (view == null)
       return;
     
     Dimension viewSize = viewport.getView().getPreferredSize();
 
     int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
     int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
     Rectangle scrollPaneBounds = SwingUtilities.calculateInnerArea(sc, null);
 
+    // If there is a viewportBorder, remove its insets from the available
+    // space.
+    Border vpBorder = sc.getViewportBorder();
+    Insets vpi;
+    if (vpBorder != null)
+      vpi = vpBorder.getBorderInsets(sc);
+    else
+      vpi = new Insets(0, 0, 0, 0);
+
     x1 = scrollPaneBounds.x;
     y1 = scrollPaneBounds.y;
     x4 = scrollPaneBounds.x + scrollPaneBounds.width;
     y4 = scrollPaneBounds.y + scrollPaneBounds.height;
     if (colHead != null)
       y2 = y1 + colHead.getPreferredSize().height;
     else
       y2 = y1;
 
     if (rowHead != null)
       x2 = x1 + rowHead.getPreferredSize().width;
     else
@@ -395,44 +425,46 @@
               || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED 
                   && viewSize.height > (y4 - y2)));
     
         if (showVsb)
           vsWidth = vsb.getPreferredSize().width;
       }
 
     x3 = x4 - vsWidth;
     y3 = y4 - hsHeight;
 
     // now set the layout
     if (viewport != null)
-      viewport.setBounds(new Rectangle(x2, y2, x3 - x2, y3 - y2));
+      viewport.setBounds(new Rectangle(x2 + vpi.left, y2 + vpi.top,
+                                       x3 - x2 - vpi.left - vpi.right,
+                                       y3 - y2 - vpi.top - vpi.bottom));
 
     if (colHead != null)
       colHead.setBounds(new Rectangle(x2, y1, x3 - x2, y2 - y1));
 
     if (rowHead != null)
       rowHead.setBounds(new Rectangle(x1, y2, x2 - x1, y3 - y2));
 
     if (showVsb)
       {
         vsb.setVisible(true);
-        vsb.setBounds(new Rectangle(x3, y2, x4 - x3, y3 - y2));
+        vsb.setBounds(new Rectangle(x3, y2, x4 - x3, y3 - y2 ));
       }
     else if (vsb != null)
       vsb.setVisible(false);
 
     if (showHsb)
       {
         hsb.setVisible(true);
-        hsb.setBounds(new Rectangle(x2, y3, x3 - x2, y4 - y3));
+        hsb.setBounds(new Rectangle(x2 , y3, x3 - x2, y4 - y3));
       }
     else if (hsb != null)
       hsb.setVisible(false);
 
     if (upperLeft != null)
       upperLeft.setBounds(new Rectangle(x1, y1, x2 - x1, y2 - y1));
 
     if (upperRight != null)
       upperRight.setBounds(new Rectangle(x3, y1, x4 - x3, y2 - y1));
 
     if (lowerLeft != null)
       lowerLeft.setBounds(new Rectangle(x1, y3, x2 - x1, y4 - y3));
Index: javax/swing/plaf/basic/BasicScrollPaneUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java,v
retrieving revision 1.27
diff -u -1 -2 -r1.27 BasicScrollPaneUI.java
--- javax/swing/plaf/basic/BasicScrollPaneUI.java	9 Jun 2006 09:58:36 -0000	1.27
+++ javax/swing/plaf/basic/BasicScrollPaneUI.java	13 Aug 2006 22:14:27 -0000
@@ -29,60 +29,59 @@
 modules, and to copy and distribute the resulting executable under
 terms of your choice, provided that you also meet, for each linked
 independent module, the terms and conditions of the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
 
 package javax.swing.plaf.basic;
 
-import gnu.classpath.NotImplementedException;
-
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
 import java.awt.event.ContainerEvent;
 import java.awt.event.ContainerListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 
 import javax.swing.AbstractAction;
-import javax.swing.Action;
 import javax.swing.ActionMap;
 import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.JScrollBar;
 import javax.swing.JScrollPane;
 import javax.swing.JSlider;
 import javax.swing.JViewport;
 import javax.swing.LookAndFeel;
 import javax.swing.ScrollPaneConstants;
 import javax.swing.ScrollPaneLayout;
 import javax.swing.Scrollable;
 import javax.swing.SwingConstants;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
+import javax.swing.border.Border;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ActionMapUIResource;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.ScrollPaneUI;
+import javax.swing.plaf.UIResource;
 
 /**
  * A UI delegate for the [EMAIL PROTECTED] JScrollPane} component.
  */
 public class BasicScrollPaneUI extends ScrollPaneUI
   implements ScrollPaneConstants
 {
 
   /**
    * Listens for changes in the state of the horizontal scrollbar's model and
    * updates the scrollpane accordingly.
    *
@@ -427,34 +426,42 @@
   public static ComponentUI createUI(final JComponent c) 
   {
     return new BasicScrollPaneUI();
   }
 
   protected void installDefaults(JScrollPane p)
   {
     scrollpane = p;
     LookAndFeel.installColorsAndFont(p, "ScrollPane.background",
                                      "ScrollPane.foreground",
                                      "ScrollPane.font");
     LookAndFeel.installBorder(p, "ScrollPane.border");
+
+    // Install Viewport border.
+    Border vpBorder = p.getViewportBorder();
+    if (vpBorder == null || vpBorder instanceof UIResource)
+      {
+        vpBorder = UIManager.getBorder("ScrollPane.viewportBorder");
+        p.setViewportBorder(vpBorder);
+      }
+
     p.setOpaque(true);
   }
 
   protected void uninstallDefaults(JScrollPane p)
   {
-    p.setForeground(null);
-    p.setBackground(null);
-    p.setFont(null);
-    p.setBorder(null);
-    scrollpane = null;
+    LookAndFeel.uninstallBorder(p);
+    Border vpBorder = p.getViewportBorder();
+    if (vpBorder != null && vpBorder instanceof UIResource)
+      p.setViewportBorder(null);
   }
     
   public void installUI(final JComponent c) 
   {
     super.installUI(c);
     installDefaults((JScrollPane) c);
     installListeners((JScrollPane) c);
     installKeyboardActions((JScrollPane) c);
   }
 
   /**
    * Installs the listeners on the scrollbars, the viewport and the scrollpane.
@@ -800,26 +807,30 @@
 
   }
 
   public Dimension getMinimumSize(JComponent c) 
   {
     JScrollPane p = (JScrollPane) c;
     ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
     return sl.minimumLayoutSize(c);
   }
 
   public void paint(Graphics g, JComponent c)
   {      
-    // do nothing; the normal painting-of-children algorithm, along with
-    // ScrollPaneLayout, does all the relevant work.
+    Border vpBorder = scrollpane.getViewportBorder();
+    if (vpBorder != null)
+      {
+        Rectangle r = scrollpane.getViewportBorderBounds();
+        vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
+      }
   }
 
   /**
    * Synchronizes the scrollbars with the viewport's extents.
    */
   protected void syncScrollPaneWithViewport()
   {
     JViewport vp = scrollpane.getViewport();
 
     // Update the horizontal scrollbar.
     JScrollBar hsb = scrollpane.getHorizontalScrollBar();
     hsb.setMaximum(vp.getViewSize().width);

Reply via email to