Frames | No Frames |
1: /* ViewportLayout.java -- 2: Copyright (C) 2002, 2004, 2006 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: package javax.swing; 39: 40: import java.awt.Component; 41: import java.awt.Container; 42: import java.awt.Dimension; 43: import java.awt.LayoutManager; 44: import java.awt.Point; 45: import java.awt.Rectangle; 46: import java.io.Serializable; 47: 48: /** 49: * The default layout for {@link JViewport}. The viewport makes its view the 50: * same size as itself, but not smaller than its minimum size. 51: * 52: * If the port extends extends into space <em>past</em> the edge of the view, 53: * this layout manager moves the port up or to the left, in view space, by the 54: * amount of empty space (keep the lower and right edges lined up). 55: * 56: * @author Andrew Selkirk 57: * @author Graydon Hoare 58: * @author Audrius Meskauskas (audriusa@Bioinformatics.org) 59: */ 60: public class ViewportLayout implements LayoutManager, Serializable 61: { 62: private static final long serialVersionUID = -788225906076097229L; 63: 64: public ViewportLayout() 65: { 66: // Nothing to do here. 67: } 68: 69: /** 70: * The method is not used with this manager. 71: */ 72: public void addLayoutComponent(String name, Component c) 73: { 74: // Nothing to do here. 75: } 76: 77: /** 78: * The method is not used with this manager. 79: */ 80: public void removeLayoutComponent(Component c) 81: { 82: // Nothing to do here. 83: } 84: 85: /** 86: * Get the preferred layout size. If the view implements 87: * {@link Scrollable}, this method returns 88: * {@link Scrollable#getPreferredScrollableViewportSize}. 89: * Otherwise, it returns {@link Component#getPreferredSize()}. 90: * 91: * @return the preferred layout size, as described about. 92: */ 93: public Dimension preferredLayoutSize(Container parent) 94: { 95: JViewport vp = (JViewport)parent; 96: Component view = vp.getView(); 97: if (view != null) 98: { 99: if (view instanceof Scrollable) 100: return ((Scrollable)view).getPreferredScrollableViewportSize(); 101: return view.getPreferredSize(); 102: } 103: else 104: return new Dimension(); 105: } 106: 107: /** 108: * Get the minimum layout size. Normally this method returns the value, 109: * returned by the view method {@link Component#getMinimumSize()}. 110: * 111: * If the view is not set, the zero size is returned. 112: * 113: * @param parent the viewport 114: * @return the minimum layout size. 115: */ 116: public Dimension minimumLayoutSize(Container parent) 117: { 118: // These values have been determined by the Mauve test for this method. 119: return new Dimension(4, 4); 120: } 121: 122: /** 123: * Layout the view and viewport to respect the following rules. These are not 124: * precisely the rules described in sun's javadocs, but they are the rules 125: * which sun's swing implementation follows, if you watch its behavior: 126: * <ol> 127: * <li>If the port is smaller than the view, leave the view at its current 128: * size.</li> 129: * <li>If the view is smaller than the port, the view is top aligned.</li> 130: * <li>If the view tracks the port size, the view position is always zero and 131: * the size equal to the viewport size</li> 132: * <li>In {@link JViewport#setViewSize(Dimension)}, the view size is never 133: * set smaller that its minimum size.</li> 134: * </ol> 135: * 136: * @see JViewport#getViewSize 137: * @see JViewport#setViewSize 138: * @see JViewport#getViewPosition 139: * @see JViewport#setViewPosition 140: */ 141: public void layoutContainer(Container parent) 142: { 143: // The way to interpret this function is basically to ignore the names 144: // of methods it calls, and focus on the variable names here. getViewRect 145: // doesn't, for example, return the view; it returns the port bounds in 146: // view space. Likwise setViewPosition doesn't reposition the view; it 147: // positions the port, in view coordinates. 148: 149: JViewport port = (JViewport) parent; 150: Component view = port.getView(); 151: 152: if (view == null) 153: return; 154: 155: // These dimensions and positions are in *view space*. Do not mix 156: // variables in here from port space (eg. parent.getBounds()). This 157: // function should be entirely in view space, because the methods on 158: // the viewport require inputs in view space. 159: 160: Rectangle portBounds = port.getViewRect(); 161: Dimension viewPref = new Dimension(view.getPreferredSize()); 162: 163: Point portLowerRight = new Point(portBounds.x + portBounds.width, 164: portBounds.y + portBounds.height); 165: 166: // vertical implementation of the above rules 167: if (view instanceof Scrollable) 168: { 169: Scrollable sView = (Scrollable) view; 170: 171: // If the view size matches viewport size, the port offset can 172: // only be zero. 173: if (sView.getScrollableTracksViewportWidth()) 174: { 175: viewPref.width = portBounds.width; 176: portBounds.x = 0; 177: } 178: if (sView.getScrollableTracksViewportHeight()) 179: { 180: viewPref.height = portBounds.height; 181: portBounds.y = 0; 182: } 183: } 184: 185: if (viewPref.width < portBounds.width) 186: viewPref.width = portBounds.width; 187: if (viewPref.height < portBounds.height) 188: viewPref.height = portBounds.height; 189: 190: // If the view is larger than the port, the port is top and right 191: // aligned. 192: if (portLowerRight.x > viewPref.width) 193: portBounds.x = 0; 194: 195: if (portLowerRight.y > viewPref.height) 196: portBounds.y = 0; 197: 198: port.setViewSize(viewPref); 199: port.setViewPosition(portBounds.getLocation()); 200: } 201: 202: }