1 /* ScrollPaneLayout.java --
2 Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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., 59 Temple Place, Suite 330, Boston, MA
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
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. */
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.Rectangle;
47 import java.awt.Point;
48 import java.io.Serializable;
49 import javax.swing.border.Border;
53 * @author Andrew Selkirk
56 public class ScrollPaneLayout
57 implements LayoutManager, ScrollPaneConstants, Serializable
59 static final long serialVersionUID = -4480022884523193743L;
61 public static class UIResource extends ScrollPaneLayout
62 implements javax.swing.plaf.UIResource {
67 protected JViewport viewport;
68 protected JScrollBar vsb;
69 protected JScrollBar hsb;
70 protected JViewport rowHead;
71 protected JViewport colHead;
72 protected Component lowerLeft;
73 protected Component lowerRight;
74 protected Component upperLeft;
75 protected Component upperRight;
76 protected int vsbPolicy;
77 protected int hsbPolicy;
79 public ScrollPaneLayout() {
83 public void syncWithScrollPane(JScrollPane scrollPane) {
84 viewport = scrollPane.getViewport();
85 rowHead = scrollPane.getRowHeader();
86 colHead = scrollPane.getColumnHeader();
87 vsb = scrollPane.getVerticalScrollBar();
88 hsb = scrollPane.getHorizontalScrollBar();
89 vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
90 hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
91 lowerLeft = scrollPane.getCorner(LOWER_LEFT_CORNER);
92 lowerRight = scrollPane.getCorner(LOWER_RIGHT_CORNER);
93 upperLeft = scrollPane.getCorner(UPPER_LEFT_CORNER);
94 upperRight = scrollPane.getCorner(UPPER_RIGHT_CORNER);
97 protected Component addSingletonComponent(Component oldComponent,
98 Component newComponent) {
102 public void addLayoutComponent(String key, Component component)
105 viewport = (JViewport) component;
106 else if (key == VERTICAL_SCROLLBAR)
107 vsb = (JScrollBar) component;
108 else if (key == HORIZONTAL_SCROLLBAR)
109 hsb = (JScrollBar) component;
110 else if (key == ROW_HEADER)
111 rowHead = (JViewport) component;
112 else if (key == COLUMN_HEADER)
113 colHead = (JViewport) component;
114 else if (key == LOWER_RIGHT_CORNER)
115 lowerRight = component;
116 else if (key == UPPER_RIGHT_CORNER)
117 upperRight = component;
118 else if (key == LOWER_LEFT_CORNER)
119 lowerLeft = component;
120 else if (key == UPPER_LEFT_CORNER)
121 upperLeft = component;
124 public void removeLayoutComponent(Component component) {
125 if (component == viewport)
127 else if (component == vsb)
129 else if (component == hsb)
131 else if (component == rowHead)
133 else if (component == colHead)
135 else if (component == lowerRight)
137 else if (component == upperRight)
139 else if (component == lowerLeft)
141 else if (component == upperLeft)
145 public int getVerticalScrollBarPolicy()
150 public void setVerticalScrollBarPolicy(int policy)
155 public int getHorizontalScrollBarPolicy()
160 public void setHorizontalScrollBarPolicy(int policy)
165 public JViewport getViewport()
170 public JScrollBar getHorizontalScrollBar()
175 public JScrollBar getVerticalScrollBar()
180 public JViewport getRowHeader()
185 public JViewport getColumnHeader()
190 public Component getCorner(String key)
192 if (key == LOWER_RIGHT_CORNER)
194 else if (key == UPPER_RIGHT_CORNER)
196 else if (key == LOWER_LEFT_CORNER)
198 else if (key == UPPER_LEFT_CORNER)
203 private static void maybeSetPreferredSize(JComponent src, Dimension dim)
205 Dimension tmp = null;
207 tmp = src.getPreferredSize();
212 private static void maybeSetMinimumSize(JComponent src, Dimension dim)
214 Dimension tmp = null;
216 tmp = src.getMinimumSize();
221 public Dimension preferredLayoutSize(Container parent)
223 if (parent != null && parent instanceof JScrollPane)
225 JScrollPane sc = (JScrollPane) parent;
226 synchronized (sc.getTreeLock ())
228 Dimension insetsSize = new Dimension(0,0);
229 Dimension viewportSize = new Dimension(0,0);
230 Dimension viewportInsetsSize = new Dimension(0,0);
231 Dimension columnHeaderSize = new Dimension(0,0);
232 Dimension rowHeaderSize = new Dimension(0,0);
233 Dimension verticalScrollBarSize = new Dimension(0,0);
234 Dimension horizontalScrollBarSize = new Dimension(0,0);
236 Insets insets = sc.getInsets();
237 Border viewportBorder = sc.getViewportBorder();
238 Insets viewportInsets = null;
240 if (viewportBorder != null)
242 viewportInsets = viewportBorder.getBorderInsets(parent);
243 if (viewportInsets != null)
244 viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
245 viewportInsets.top + viewportInsets.bottom);
249 insetsSize.setSize(insets.left + insets.right,
250 insets.top + insets.bottom);
252 if (viewport != null)
254 Component view = null;
255 Scrollable scr = null;
256 Dimension pref = null;
258 view = viewport.getView();
259 if (view != null && view instanceof Scrollable)
260 scr = (Scrollable) view;
262 pref = scr.getPreferredScrollableViewportSize();
264 pref = viewport.getPreferredSize();
266 viewportSize.setSize(pref);
269 maybeSetPreferredSize(colHead, columnHeaderSize);
270 maybeSetPreferredSize(rowHead, rowHeaderSize);
271 maybeSetPreferredSize(vsb, verticalScrollBarSize);
272 maybeSetPreferredSize(hsb, horizontalScrollBarSize);
274 return new Dimension(insetsSize.width
276 + viewportInsetsSize.width
277 + rowHeaderSize.width
278 + verticalScrollBarSize.width,
280 + viewportSize.height
281 + viewportInsetsSize.height
282 + columnHeaderSize.height
283 + horizontalScrollBarSize.height);
288 return new Dimension(0,0);
292 public Dimension minimumLayoutSize(Container parent)
294 if (parent instanceof JScrollPane)
296 JScrollPane sc = (JScrollPane) parent;
297 synchronized (sc.getTreeLock ())
299 Dimension insetsSize = new Dimension(0,0);
300 Dimension viewportSize = new Dimension(0,0);
301 Dimension viewportInsetsSize = new Dimension(0,0);
302 Dimension columnHeaderSize = new Dimension(0,0);
303 Dimension rowHeaderSize = new Dimension(0,0);
304 Dimension verticalScrollBarSize = new Dimension(0,0);
305 Dimension horizontalScrollBarSize = new Dimension(0,0);
307 Insets insets = sc.getInsets();
308 Border viewportBorder = sc.getViewportBorder();
309 Insets viewportInsets = null;
311 if (viewportBorder != null)
313 viewportInsets = viewportBorder.getBorderInsets(parent);
314 if (viewportInsets != null)
315 viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
316 viewportInsets.top + viewportInsets.bottom);
320 insetsSize.setSize(insets.left + insets.right,
321 insets.top + insets.bottom);
323 maybeSetMinimumSize(viewport, viewportSize);
324 maybeSetMinimumSize(colHead, columnHeaderSize);
325 maybeSetMinimumSize(rowHead, rowHeaderSize);
327 if (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)
328 maybeSetMinimumSize(vsb, verticalScrollBarSize);
330 if (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)
331 maybeSetMinimumSize(hsb, horizontalScrollBarSize);
333 return new Dimension(insetsSize.width
335 + viewportInsetsSize.width
336 + rowHeaderSize.width
337 + verticalScrollBarSize.width,
339 + viewportSize.height
340 + viewportInsetsSize.height
341 + columnHeaderSize.height
342 + horizontalScrollBarSize.height);
347 return new Dimension(0,0);
353 * +----+--------------------+----+ y1
354 * | c1 | column header | c2 |
355 * +----+--------------------+----+ y2
361 * | e | viewport | l |
366 * +----+--------------------+----+ y3
367 * | c3 | h scrollbar | c4 |
368 * +----+--------------------+----+ y4
372 public void layoutContainer(Container parent)
374 if (parent instanceof JScrollPane)
376 JScrollPane sc = (JScrollPane) parent;
377 synchronized (sc.getTreeLock ())
379 JViewport viewport = sc.getViewport();
380 Dimension viewSize = viewport.getViewSize();
381 Point viewPos = viewport.getViewPosition();
383 int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
384 int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
386 Rectangle scrollPaneBounds = SwingUtilities.calculateInnerArea(sc, null);
388 x1 = scrollPaneBounds.x;
389 y1 = scrollPaneBounds.y;
390 x4 = scrollPaneBounds.x + scrollPaneBounds.width;
391 y4 = scrollPaneBounds.y + scrollPaneBounds.height;
394 y2 = y1 + colHead.getPreferredSize().height;
399 x2 = x1 + rowHead.getPreferredSize().width;
403 int vsbPolicy = sc.getVerticalScrollBarPolicy();
404 int hsbPolicy = sc.getHorizontalScrollBarPolicy();
406 x3 = x4 - vsb.getPreferredSize().width;
407 y3 = y4 - hsb.getPreferredSize().height;
411 && ((vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS)
412 || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED
413 && viewSize.height > (y3 - y2)));
417 && ((hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS)
418 || (hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED
419 && viewSize.width > (x3 - x2)));
427 // now set the layout
429 if (viewport != null)
430 viewport.setBounds(new Rectangle(x2, y2, x3-x2, y3-y2));
433 colHead.setBounds(new Rectangle(x2, y1, x3-x2, y2-y1));
436 rowHead.setBounds(new Rectangle(x1, y2, x2-x1, y3-y2));
440 vsb.setVisible(true);
441 vsb.setBounds(new Rectangle(x3, y2, x4-x3, y3-y2));
443 else if (vsb != null)
444 vsb.setVisible(false);
448 hsb.setVisible(true);
449 hsb.setBounds(new Rectangle(x2, y3, x3-x2, y4-y3));
451 else if (hsb != null)
452 hsb.setVisible(false);
454 if (upperLeft != null)
455 upperLeft.setBounds(new Rectangle(x1, y1, x2-x1, y2-y1));
457 if (upperRight != null)
458 upperRight.setBounds(new Rectangle(x3, y1, x4-x3, y2-y1));
460 if (lowerLeft != null)
461 lowerLeft.setBounds(new Rectangle(x1, y3, x2-x1, y4-y3));
463 if (lowerRight != null)
464 lowerRight.setBounds(new Rectangle(x3, y3, x4-x3, y4-y3));
470 public Rectangle getViewportBorderBounds(JScrollPane scrollPane) {