1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * @(#)FlowLayout.java 1.18 95/12/14 Arthur van Hoff 26 * 27 * Copyright (c) 1994, 2001 by Sun Microsystems, Inc. 28 * All rights reserved. 29 * 30 * Permission to use, copy, modify, and distribute this software 31 * and its documentation for NON-COMMERCIAL purposes and without 32 * fee is hereby granted provided that this copyright notice 33 * appears in all copies. Please refer to the file "copyright.html" 34 * for further important copyright and licensing information. 35 * 36 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF 37 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 38 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 39 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR 40 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 41 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. 42 */ 43 package sunsoft.jws.visual.rt.awt; 44 45 import java.awt.*; 46 47 /** 48 * Flow layout is used to layout buttons in a panel. It will arrange 49 * buttons left to right until no more buttons fit on the same line. 50 * Each line is centered. 51 * 52 * @version 1.18, 14 Dec 1995 53 * @author Arthur van Hoff 54 * @author Sami Shaio 55 */ 56 public class VJFlowLayout implements LayoutManager { 57 58 /** 59 * The left alignment variable. 60 */ 61 public static final int LEFT = 0; 62 63 /** 64 * The right alignment variable. 65 */ 66 public static final int CENTER = 1; 67 68 /** 69 * The right alignment variable. 70 */ 71 public static final int RIGHT = 2; 72 73 // Private variables 74 private static final int PREFERREDSIZE = 0; 75 private static final int MINIMUMSIZE = 1; 76 77 private int align; 78 private int hgap; 79 private int vgap; 80 81 private int minimumWidth; 82 83 /** 84 * Constructs a new Flow Layout with a centered alignment. 85 */ VJFlowLayout()86 public VJFlowLayout() { 87 this.align = LEFT; 88 this.hgap = 5; 89 this.vgap = 5; 90 this.minimumWidth = 0; 91 } 92 setAlignment(int align)93 public void setAlignment(int align) { 94 this.align = align; 95 } 96 getAlignment()97 public int getAlignment() { 98 return align; 99 } 100 setHGap(int hgap)101 public void setHGap(int hgap) { 102 this.hgap = hgap; 103 } 104 getHGap()105 public int getHGap() { 106 return hgap; 107 } 108 setVGap(int vgap)109 public void setVGap(int vgap) { 110 this.vgap = vgap; 111 } 112 getVGap()113 public int getVGap() { 114 return vgap; 115 } 116 setMinimumWidth(int width)117 public void setMinimumWidth(int width) { 118 this.minimumWidth = width; 119 } 120 getMinimumWidth()121 public int getMinimumWidth() { 122 return minimumWidth; 123 } 124 125 /** 126 * Adds the specified component to the layout. 127 * Not used by this class. 128 * @param name the name of the component 129 * @param comp the the component to be added 130 */ addLayoutComponent(String name, Component comp)131 public void addLayoutComponent(String name, Component comp) { 132 } 133 134 /** 135 * Removes the specified component from the layout. Not used by 136 * this class. 137 * @param comp the component to remove 138 */ removeLayoutComponent(Component comp)139 public void removeLayoutComponent(Component comp) { 140 } 141 142 /** 143 * Returns the preferred dimensions for 144 * this layout given the components 145 * in the specified target container. 146 * @param target the component which needs to be laid out 147 * @see Container 148 * @see #minimumLayoutSize 149 */ preferredLayoutSize(Container target)150 public Dimension preferredLayoutSize(Container target) { 151 return calcLayoutSize(target, PREFERREDSIZE); 152 } 153 154 /** 155 * Returns the minimum dimensions needed to layout the components 156 * contained in the specified target container. 157 * @param target the component which needs to be laid out 158 * @see #preferredLayoutSize 159 */ minimumLayoutSize(Container target)160 public Dimension minimumLayoutSize(Container target) { 161 return calcLayoutSize(target, MINIMUMSIZE); 162 } 163 calcLayoutSize(Container target, int which)164 private Dimension calcLayoutSize(Container target, int which) { 165 Insets insets = target.insets(); 166 Dimension r = new Dimension(0, vgap + insets.top + 167 insets.bottom); 168 int nmembers = target.countComponents(); 169 int rowCount = 0; 170 int rowWidth = insets.left + insets.right + hgap; 171 int rowHeight = 0; 172 173 for (int i = 0; i < nmembers; i++) { 174 Component m = target.getComponent(i); 175 176 if (m.isVisible()) { 177 Dimension d; 178 if (which == PREFERREDSIZE) 179 d = m.preferredSize(); 180 else 181 d = m.minimumSize(); 182 183 if (minimumWidth > 0 && rowCount != 0 && 184 rowWidth + d.width + hgap > minimumWidth) { 185 186 r.width = Math.max(rowWidth, r.width); 187 r.height += (rowHeight + vgap); 188 189 rowCount = 0; 190 rowWidth = insets.left + insets.right + hgap; 191 rowHeight = 0; 192 } 193 194 rowWidth += (d.width + hgap); 195 rowHeight = Math.max(rowHeight, d.height); 196 rowCount++; 197 } 198 } 199 200 if (rowCount > 0) { 201 r.width = Math.max(rowWidth, r.width); 202 r.height += (rowHeight + vgap); 203 } 204 205 return r; 206 } 207 208 /** 209 * Centers the elements in the specified row, if there is any slack. 210 * @param target the component which needs to be moved 211 * @param x the x coordinate 212 * @param y the y coordinate 213 * @param width the width dimensions 214 * @param height the height dimensions 215 * @param rowStart the beginning of the row 216 * @param rowEnd the the ending of the row 217 */ moveComponents(Container target, int x, int y, int width, int height, int rowStart, int rowEnd)218 private void moveComponents(Container target, int x, int y, 219 int width, int height, int rowStart, int rowEnd) { 220 switch (align) { 221 case LEFT: 222 break; 223 case CENTER: 224 x += width / 2; 225 break; 226 case RIGHT: 227 x += width; 228 break; 229 } 230 for (int i = rowStart; i < rowEnd; i++) { 231 Component m = target.getComponent(i); 232 if (m.isVisible()) { 233 Dimension size = m.size(); 234 m.move(x, y + (height - size.height) / 2); 235 x += hgap + size.width; 236 } 237 } 238 } 239 240 /** 241 * Lays out the container. This method will actually reshape the 242 * components in the target in order to satisfy the constraints of 243 * the BorderLayout object. 244 * @param target the specified component being laid out. 245 * @see Container 246 */ layoutContainer(Container target)247 public void layoutContainer(Container target) { 248 Insets insets = target.insets(); 249 Dimension size = target.size(); 250 int maxwidth = size.width - (insets.left + insets.right + 251 hgap*2); 252 int nmembers = target.countComponents(); 253 int x = 0, y = insets.top + vgap; 254 int rowh = 0, start = 0; 255 256 for (int i = 0; i < nmembers; i++) { 257 Component m = target.getComponent(i); 258 if (m.isVisible()) { 259 Dimension d = m.preferredSize(); 260 m.resize(d.width, d.height); 261 262 if ((x == 0) || ((x + d.width) <= maxwidth)) { 263 if (x > 0) { 264 x += hgap; 265 } 266 x += d.width; 267 rowh = Math.max(rowh, d.height); 268 } else { 269 moveComponents(target, insets.left + hgap, 270 y, maxwidth - x, rowh, start, i); 271 x = d.width; 272 y += vgap + rowh; 273 rowh = d.height; 274 start = i; 275 } 276 } 277 } 278 moveComponents(target, insets.left + hgap, y, 279 maxwidth - x, rowh, start, nmembers); 280 } 281 282 /** 283 * Returns the String representation of this FlowLayout's values. 284 */ toString()285 public String toString() { 286 String str = /* NOI18N */""; 287 switch (align) { 288 case LEFT: str = /* NOI18N */",align=left"; break; 289 case CENTER: str = /* NOI18N */",align=center"; break; 290 case RIGHT: str = /* NOI18N */",align=right"; break; 291 } 292 return getClass().getName() + /* NOI18N */"[hgap=" + 293 hgap + /* NOI18N */",vgap=" + vgap + str + /* NOI18N */"]"; 294 } 295 } 296