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.Point;
47 import java.awt.Rectangle;
48 import java.io.Serializable;
50 import javax.swing.border.Border;
54 * @author Andrew Selkirk
57 public class ScrollPaneLayout
58 implements LayoutManager, ScrollPaneConstants, Serializable
60 static final long serialVersionUID = -4480022884523193743L;
62 public static class UIResource extends ScrollPaneLayout
63 implements javax.swing.plaf.UIResource {
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;
80 public ScrollPaneLayout() {
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);
98 protected Component addSingletonComponent(Component oldComponent,
99 Component newComponent) {
103 public void addLayoutComponent(String key, Component component)
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;
125 public void removeLayoutComponent(Component component) {
126 if (component == viewport)
128 else if (component == vsb)
130 else if (component == hsb)
132 else if (component == rowHead)
134 else if (component == colHead)
136 else if (component == lowerRight)
138 else if (component == upperRight)
140 else if (component == lowerLeft)
142 else if (component == upperLeft)
146 public int getVerticalScrollBarPolicy()
151 public void setVerticalScrollBarPolicy(int policy)
156 public int getHorizontalScrollBarPolicy()
161 public void setHorizontalScrollBarPolicy(int policy)
166 public JViewport getViewport()
171 public JScrollBar getHorizontalScrollBar()
176 public JScrollBar getVerticalScrollBar()
181 public JViewport getRowHeader()
186 public JViewport getColumnHeader()
191 public Component getCorner(String key)
193 if (key == LOWER_RIGHT_CORNER)
195 else if (key == UPPER_RIGHT_CORNER)
197 else if (key == LOWER_LEFT_CORNER)
199 else if (key == UPPER_LEFT_CORNER)
204 private static void maybeSetPreferredSize(JComponent src, Dimension dim)
206 Dimension tmp = null;
208 tmp = src.getPreferredSize();
213 private static void maybeSetMinimumSize(JComponent src, Dimension dim)
215 Dimension tmp = null;
217 tmp = src.getMinimumSize();
222 public Dimension preferredLayoutSize(Container parent)
224 if (parent != null && parent instanceof JScrollPane)
226 JScrollPane sc = (JScrollPane) parent;
227 synchronized (sc.getTreeLock ())
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);
237 Insets insets = sc.getInsets();
238 Border viewportBorder = sc.getViewportBorder();
239 Insets viewportInsets = null;
241 if (viewportBorder != null)
243 viewportInsets = viewportBorder.getBorderInsets(parent);
244 if (viewportInsets != null)
245 viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
246 viewportInsets.top + viewportInsets.bottom);
250 insetsSize.setSize(insets.left + insets.right,
251 insets.top + insets.bottom);
253 if (viewport != null)
255 Component view = null;
256 Scrollable scr = null;
257 Dimension pref = null;
259 view = viewport.getView();
260 if (view != null && view instanceof Scrollable)
261 scr = (Scrollable) view;
263 pref = scr.getPreferredScrollableViewportSize();
265 pref = viewport.getPreferredSize();
267 viewportSize.setSize(pref);
270 maybeSetPreferredSize(colHead, columnHeaderSize);
271 maybeSetPreferredSize(rowHead, rowHeaderSize);
272 maybeSetPreferredSize(vsb, verticalScrollBarSize);
273 maybeSetPreferredSize(hsb, horizontalScrollBarSize);
275 return new Dimension(insetsSize.width
277 + viewportInsetsSize.width
278 + rowHeaderSize.width
279 + verticalScrollBarSize.width,
281 + viewportSize.height
282 + viewportInsetsSize.height
283 + columnHeaderSize.height
284 + horizontalScrollBarSize.height);
289 return new Dimension(0,0);
293 public Dimension minimumLayoutSize(Container parent)
295 if (parent instanceof JScrollPane)
297 JScrollPane sc = (JScrollPane) parent;
298 synchronized (sc.getTreeLock ())
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);
308 Insets insets = sc.getInsets();
309 Border viewportBorder = sc.getViewportBorder();
310 Insets viewportInsets = null;
312 if (viewportBorder != null)
314 viewportInsets = viewportBorder.getBorderInsets(parent);
315 if (viewportInsets != null)
316 viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
317 viewportInsets.top + viewportInsets.bottom);
321 insetsSize.setSize(insets.left + insets.right,
322 insets.top + insets.bottom);
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) {