Source for javax.swing.ScrollPaneLayout

   1: /* ScrollPaneLayout.java --
   2:    Copyright (C) 2002, 2004  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing;
  40: 
  41: import java.awt.Component;
  42: import java.awt.Container;
  43: import java.awt.Dimension;
  44: import java.awt.Insets;
  45: import java.awt.LayoutManager;
  46: import java.awt.Point;
  47: import java.awt.Rectangle;
  48: import java.io.Serializable;
  49: 
  50: import javax.swing.border.Border;
  51: 
  52: /**
  53:  * ScrollPaneLayout
  54:  * @author    Andrew Selkirk
  55:  * @version    1.0
  56:  */
  57: public class ScrollPaneLayout
  58:   implements LayoutManager, ScrollPaneConstants, Serializable
  59: {
  60:   private static final long serialVersionUID = -4480022884523193743L;
  61: 
  62:   public static class UIResource extends ScrollPaneLayout 
  63:     implements javax.swing.plaf.UIResource {
  64:     public UIResource() {
  65:     }
  66:   }
  67: 
  68:   protected JViewport viewport;
  69:   protected JScrollBar vsb;
  70:   protected JScrollBar hsb;
  71:   protected JViewport rowHead;
  72:   protected JViewport colHead;
  73:   protected Component lowerLeft;
  74:   protected Component lowerRight;
  75:   protected Component upperLeft;
  76:   protected Component upperRight;
  77:   protected int vsbPolicy;
  78:   protected int hsbPolicy;
  79: 
  80:   public ScrollPaneLayout() {
  81:         
  82:   }
  83: 
  84:   public void syncWithScrollPane(JScrollPane scrollPane) {
  85:     viewport = scrollPane.getViewport();
  86:     rowHead = scrollPane.getRowHeader();
  87:     colHead = scrollPane.getColumnHeader();
  88:     vsb = scrollPane.getVerticalScrollBar();
  89:     hsb = scrollPane.getHorizontalScrollBar();
  90:     vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
  91:     hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
  92:     lowerLeft = scrollPane.getCorner(LOWER_LEFT_CORNER);
  93:     lowerRight = scrollPane.getCorner(LOWER_RIGHT_CORNER);
  94:     upperLeft = scrollPane.getCorner(UPPER_LEFT_CORNER);
  95:     upperRight = scrollPane.getCorner(UPPER_RIGHT_CORNER);    
  96:   }
  97: 
  98:   protected Component addSingletonComponent(Component oldComponent,
  99:                                             Component newComponent) {
 100:     return null;
 101:   }
 102: 
 103:   public void addLayoutComponent(String key, Component component) 
 104:   {
 105:     if (key == VIEWPORT)
 106:       viewport = (JViewport) component;
 107:     else if (key == VERTICAL_SCROLLBAR)
 108:       vsb = (JScrollBar) component;
 109:     else if (key == HORIZONTAL_SCROLLBAR)
 110:       hsb = (JScrollBar) component;
 111:     else if (key == ROW_HEADER)
 112:       rowHead = (JViewport) component;
 113:     else if (key == COLUMN_HEADER)
 114:       colHead = (JViewport) component;
 115:     else if (key == LOWER_RIGHT_CORNER)
 116:       lowerRight = component;
 117:     else if (key == UPPER_RIGHT_CORNER)
 118:       upperRight = component;
 119:     else if (key == LOWER_LEFT_CORNER)
 120:       lowerLeft = component;
 121:     else if (key == UPPER_LEFT_CORNER)
 122:       upperLeft = component;
 123:   }
 124: 
 125:   public void removeLayoutComponent(Component component) {
 126:     if (component == viewport)
 127:       viewport = null;
 128:     else if (component == vsb)
 129:       vsb = null;
 130:     else if (component == hsb)
 131:       hsb = null;
 132:     else if (component == rowHead)
 133:       rowHead = null;
 134:     else if (component == colHead)
 135:       colHead = null;
 136:     else if (component == lowerRight)
 137:       lowerRight = null;
 138:     else if (component == upperRight)
 139:       upperRight = null;
 140:     else if (component == lowerLeft)
 141:       lowerLeft = null;
 142:     else if (component == upperLeft)
 143:       upperLeft = null;
 144:   }
 145: 
 146:   public int getVerticalScrollBarPolicy()
 147:   {
 148:     return vsbPolicy;
 149:   }
 150: 
 151:   public void setVerticalScrollBarPolicy(int policy)
 152:   {
 153:     vsbPolicy = policy;
 154:   }
 155: 
 156:   public int getHorizontalScrollBarPolicy()
 157:   {
 158:     return hsbPolicy;
 159:   }
 160: 
 161:   public void setHorizontalScrollBarPolicy(int policy)
 162:   {
 163:     hsbPolicy = policy;
 164:   }
 165: 
 166:   public JViewport getViewport()
 167:   {
 168:     return viewport;
 169:   }
 170: 
 171:   public JScrollBar getHorizontalScrollBar()
 172:   {
 173:     return hsb;
 174:   }
 175: 
 176:   public JScrollBar getVerticalScrollBar()
 177:   {
 178:     return vsb;
 179:   }
 180: 
 181:   public JViewport getRowHeader()
 182:   {
 183:     return rowHead;
 184:   }
 185: 
 186:   public JViewport getColumnHeader()
 187:   {
 188:     return colHead;
 189:   }
 190: 
 191:   public Component getCorner(String key)
 192:   {
 193:     if (key == LOWER_RIGHT_CORNER)
 194:       return lowerRight;
 195:     else if (key == UPPER_RIGHT_CORNER)
 196:       return upperRight;
 197:     else if (key == LOWER_LEFT_CORNER)
 198:       return lowerLeft;
 199:     else if (key == UPPER_LEFT_CORNER)
 200:       return upperLeft;
 201:     return null;
 202:   }
 203: 
 204:   private static void maybeSetPreferredSize(JComponent src, Dimension dim)
 205:   {
 206:     Dimension tmp = null;
 207:     if (src != null)
 208:       tmp = src.getPreferredSize();
 209:     if (tmp != null)
 210:       dim.setSize(tmp);        
 211:   }
 212: 
 213:   private static void maybeSetMinimumSize(JComponent src, Dimension dim)
 214:   {
 215:     Dimension tmp = null;
 216:     if (src != null)
 217:       tmp = src.getMinimumSize();
 218:     if (tmp != null)
 219:       dim.setSize(tmp);
 220:   }
 221: 
 222:   public Dimension preferredLayoutSize(Container parent) 
 223:   {
 224:     if (parent != null && parent instanceof JScrollPane)
 225:       {
 226:         JScrollPane sc = (JScrollPane) parent;
 227:         synchronized (sc.getTreeLock ())
 228:           {
 229:             Dimension insetsSize = new Dimension(0,0); 
 230:             Dimension viewportSize = new Dimension(0,0); 
 231:             Dimension viewportInsetsSize = new Dimension(0,0); 
 232:             Dimension columnHeaderSize = new Dimension(0,0); 
 233:             Dimension rowHeaderSize = new Dimension(0,0); 
 234:             Dimension verticalScrollBarSize = new Dimension(0,0); 
 235:             Dimension horizontalScrollBarSize = new Dimension(0,0); 
 236: 
 237:             Insets insets = sc.getInsets();
 238:             Border viewportBorder = sc.getViewportBorder();
 239:             Insets viewportInsets = null;
 240: 
 241:             if (viewportBorder != null)
 242:               {
 243:                 viewportInsets = viewportBorder.getBorderInsets(parent);
 244:                 if (viewportInsets != null)
 245:                   viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
 246:                                              viewportInsets.top + viewportInsets.bottom);
 247:               }
 248: 
 249:             if (insets != null)
 250:               insetsSize.setSize(insets.left + insets.right,
 251:                                  insets.top + insets.bottom);
 252: 
 253:             if (viewport != null)
 254:               {
 255:                 Component view = null;
 256:                 Scrollable scr = null;
 257:                 Dimension pref = null;
 258:                 
 259:                 view = viewport.getView();
 260:                 if (view != null && view instanceof Scrollable)
 261:                   scr = (Scrollable) view;
 262:                 if (scr != null)
 263:                   pref = scr.getPreferredScrollableViewportSize();
 264:                 if (pref == null)
 265:                   pref = viewport.getPreferredSize();
 266:                 if (pref != null)
 267:                   viewportSize.setSize(pref);
 268:               }
 269:                        
 270:             maybeSetPreferredSize(colHead, columnHeaderSize);
 271:             maybeSetPreferredSize(rowHead, rowHeaderSize);
 272:             maybeSetPreferredSize(vsb, verticalScrollBarSize);
 273:             maybeSetPreferredSize(hsb, horizontalScrollBarSize);
 274: 
 275:             return new Dimension(insetsSize.width 
 276:                                  + viewportSize.width
 277:                                  + viewportInsetsSize.width
 278:                                  + rowHeaderSize.width
 279:                                  + verticalScrollBarSize.width,
 280:                                  insetsSize.height
 281:                                  + viewportSize.height
 282:                                  + viewportInsetsSize.height
 283:                                  + columnHeaderSize.height
 284:                                  + horizontalScrollBarSize.height);
 285:           }
 286:       }
 287:     else
 288:       {
 289:         return new Dimension(0,0);
 290:       }
 291:   }
 292: 
 293:   public Dimension minimumLayoutSize(Container parent)
 294:   {
 295:     if (parent instanceof JScrollPane)
 296:       {
 297:         JScrollPane sc = (JScrollPane) parent;
 298:         synchronized (sc.getTreeLock ())
 299:           {
 300:             Dimension insetsSize = new Dimension(0,0); 
 301:             Dimension viewportSize = new Dimension(0,0); 
 302:             Dimension viewportInsetsSize = new Dimension(0,0); 
 303:             Dimension columnHeaderSize = new Dimension(0,0); 
 304:             Dimension rowHeaderSize = new Dimension(0,0); 
 305:             Dimension verticalScrollBarSize = new Dimension(0,0); 
 306:             Dimension horizontalScrollBarSize = new Dimension(0,0); 
 307: 
 308:             Insets insets = sc.getInsets();
 309:             Border viewportBorder = sc.getViewportBorder();
 310:             Insets viewportInsets = null;
 311: 
 312:             if (viewportBorder != null)
 313:               {
 314:                 viewportInsets = viewportBorder.getBorderInsets(parent);
 315:                 if (viewportInsets != null)
 316:                   viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
 317:                                              viewportInsets.top + viewportInsets.bottom);
 318:               }
 319:             
 320:             if (insets != null)
 321:               insetsSize.setSize(insets.left + insets.right,
 322:                                  insets.top + insets.bottom);
 323: 
 324:             maybeSetMinimumSize(colHead, columnHeaderSize);
 325:             maybeSetMinimumSize(rowHead, rowHeaderSize);
 326:             
 327:             if (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)
 328:               maybeSetMinimumSize(vsb, verticalScrollBarSize);
 329: 
 330:             if (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)
 331:               maybeSetMinimumSize(hsb, horizontalScrollBarSize);
 332:             
 333:             return new Dimension(insetsSize.width 
 334:                                  + viewportSize.width
 335:                                  + viewportInsetsSize.width
 336:                                  + rowHeaderSize.width
 337:                                  + verticalScrollBarSize.width,
 338:                                  insetsSize.height
 339:                                  + viewportSize.height
 340:                                  + viewportInsetsSize.height
 341:                                  + columnHeaderSize.height
 342:                                  + horizontalScrollBarSize.height);
 343:           }
 344:       }
 345:     else
 346:       {
 347:         return new Dimension(0,0);
 348:       }
 349:   }
 350: 
 351:   /**
 352:    *
 353:    *     +----+--------------------+----+ y1
 354:    *     | c1 |   column header    | c2 |
 355:    *     +----+--------------------+----+ y2
 356:    *     | r  |                    | v  |
 357:    *     | o  |                    |    |
 358:    *     | w  |                    | s  |
 359:    *     |    |                    | r  |
 360:    *     | h  |                    | o  |
 361:    *     | e  |      viewport      | l  |
 362:    *     | a  |                    | l  |
 363:    *     | d  |                    | b  |
 364:    *     | e  |                    | a  |
 365:    *     | r  |                    | r  |
 366:    *     +----+--------------------+----+ y3
 367:    *     | c3 |    h scrollbar     | c4 |
 368:    *     +----+--------------------+----+ y4
 369:    *    x1   x2                   x3   x4
 370:    *   
 371:    */
 372:   public void layoutContainer(Container parent)
 373:   {
 374:     if (parent instanceof JScrollPane)
 375:       {
 376:         JScrollPane sc = (JScrollPane) parent;
 377:         synchronized (sc.getTreeLock ())
 378:           {
 379:             JViewport viewport = sc.getViewport();
 380:             Dimension viewSize = viewport.getViewSize(); 
 381:             Point viewPos = viewport.getViewPosition(); 
 382: 
 383:             int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
 384:             int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
 385: 
 386:             Rectangle scrollPaneBounds = SwingUtilities.calculateInnerArea(sc, null);
 387: 
 388:             x1 = scrollPaneBounds.x;
 389:             y1 = scrollPaneBounds.y;
 390:             x4 = scrollPaneBounds.x + scrollPaneBounds.width;
 391:             y4 = scrollPaneBounds.y + scrollPaneBounds.height;
 392:             
 393:             if (colHead != null)
 394:               y2 = y1 + colHead.getPreferredSize().height;
 395:             else
 396:               y2 = y1;
 397: 
 398:             if (rowHead != null)
 399:               x2 = x1 + rowHead.getPreferredSize().width;
 400:             else
 401:               x2 = x1;
 402: 
 403:             int vsbPolicy = sc.getVerticalScrollBarPolicy();
 404:             int hsbPolicy = sc.getHorizontalScrollBarPolicy();
 405: 
 406:             x3 = x4 - vsb.getPreferredSize().width;
 407:             y3 = y4 - hsb.getPreferredSize().height;
 408: 
 409:             boolean showVsb = 
 410:               (vsb != null)
 411:               && ((vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS)
 412:                   || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED 
 413:                       && viewSize.height > (y3 - y2)));
 414: 
 415:             boolean showHsb = 
 416:               (hsb != null)
 417:               && ((hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS)
 418:                   || (hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED 
 419:                       && viewSize.width > (x3 - x2)));
 420:             
 421:             if (!showVsb)
 422:               x3 = x4;
 423:             
 424:             if (!showHsb)
 425:               y3 = y4;
 426: 
 427:             // now set the layout
 428: 
 429:             if (viewport != null)
 430:               viewport.setBounds(new Rectangle(x2, y2, x3-x2, y3-y2));
 431: 
 432:             if (colHead != null)
 433:               colHead.setBounds(new Rectangle(x2, y1, x3-x2, y2-y1));
 434: 
 435:             if (rowHead != null)
 436:               rowHead.setBounds(new Rectangle(x1, y2, x2-x1, y3-y2));
 437: 
 438:             if (showVsb)
 439:               {
 440:                 vsb.setVisible(true);
 441:                 vsb.setBounds(new Rectangle(x3, y2, x4-x3, y3-y2));
 442:               }
 443:             else if (vsb != null)
 444:               vsb.setVisible(false);
 445: 
 446:             if (showHsb)
 447:               {
 448:                 hsb.setVisible(true);
 449:                 hsb.setBounds(new Rectangle(x2, y3, x3-x2, y4-y3));
 450:               }
 451:             else if (hsb != null)
 452:               hsb.setVisible(false);
 453: 
 454:             if (upperLeft != null)
 455:               upperLeft.setBounds(new Rectangle(x1, y1, x2-x1, y2-y1));
 456: 
 457:             if (upperRight != null)
 458:               upperRight.setBounds(new Rectangle(x3, y1, x4-x3, y2-y1));
 459: 
 460:             if (lowerLeft != null)
 461:               lowerLeft.setBounds(new Rectangle(x1, y3, x2-x1, y4-y3));
 462: 
 463:             if (lowerRight != null)
 464:               lowerRight.setBounds(new Rectangle(x3, y3, x4-x3, y4-y3));
 465: 
 466:           }
 467:       }
 468:   }
 469: 
 470:   /**
 471:    * Returns the bounds of the border around a ScrollPane's viewport.
 472:    *
 473:    * @param scrollPane the ScrollPane for which's viewport the border
 474:    *     is requested
 475:    *
 476:    * @deprecated As of Swing 1.1 replaced by
 477:    *     {@link javax.swing.JScrollPane#getViewportBorderBounds}.
 478:    */
 479:   public Rectangle getViewportBorderBounds(JScrollPane scrollPane) {
 480:     return null;
 481:   }
 482: 
 483: 
 484: }