1 /* ======================================================================== 2 * JCommon : a free general purpose class library for the Java(tm) platform 3 * ======================================================================== 4 * 5 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 6 * 7 * Project Info: http://www.jfree.org/jcommon/index.html 8 * 9 * This library is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU Lesser General Public License as published by 11 * the Free Software Foundation; either version 2.1 of the License, or 12 * (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17 * License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22 * USA. 23 * 24 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25 * in the United States and other countries.] 26 * 27 * -------------- 28 * LCBLayout.java 29 * -------------- 30 * (C) Copyright 2000-2005, by Object Refinery Limited. 31 * 32 * Original Author: David Gilbert (for Object Refinery Limited); 33 * Contributor(s): -; 34 * 35 * $Id: LCBLayout.java,v 1.5 2005/11/16 15:58:40 taqua Exp $ 36 * 37 * Changes (from 26-Oct-2001) 38 * -------------------------- 39 * 26-Oct-2001 : Changed package to com.jrefinery.layout.* (DG); 40 * 10-Oct-2002 : Fixed errors reported by Checkstyle (DG); 41 */ 42 43 package org.jfree.layout; 44 45 import java.awt.Component; 46 import java.awt.Container; 47 import java.awt.Dimension; 48 import java.awt.Insets; 49 import java.awt.LayoutManager; 50 import java.io.Serializable; 51 52 /** 53 * Specialised layout manager for a grid of components. 54 * 55 * @author David Gilbert 56 */ 57 public class LCBLayout implements LayoutManager, Serializable { 58 59 /** For serialization. */ 60 private static final long serialVersionUID = -2531780832406163833L; 61 62 /** A constant for the number of columns in the layout. */ 63 private static final int COLUMNS = 3; 64 65 /** Tracks the column widths. */ 66 private int[] colWidth; 67 68 /** Tracks the row heights. */ 69 private int[] rowHeight; 70 71 /** The gap between each label and component. */ 72 private int labelGap; 73 74 /** The gap between each component and button. */ 75 private int buttonGap; 76 77 /** The gap between rows. */ 78 private int vGap; 79 80 /** 81 * Creates a new LCBLayout with the specified maximum number of rows. 82 * 83 * @param maxrows the maximum number of rows. 84 */ LCBLayout(final int maxrows)85 public LCBLayout(final int maxrows) { 86 this.labelGap = 10; 87 this.buttonGap = 6; 88 this.vGap = 2; 89 this.colWidth = new int[COLUMNS]; 90 this.rowHeight = new int[maxrows]; 91 } 92 93 /** 94 * Returns the preferred size using this layout manager. 95 * 96 * @param parent the parent. 97 * 98 * @return the preferred size using this layout manager. 99 */ preferredLayoutSize(final Container parent)100 public Dimension preferredLayoutSize(final Container parent) { 101 102 synchronized (parent.getTreeLock()) { 103 final Insets insets = parent.getInsets(); 104 final int ncomponents = parent.getComponentCount(); 105 final int nrows = ncomponents / COLUMNS; 106 for (int c = 0; c < COLUMNS; c++) { 107 for (int r = 0; r < nrows; r++) { 108 final Component component 109 = parent.getComponent(r * COLUMNS + c); 110 final Dimension d = component.getPreferredSize(); 111 if (this.colWidth[c] < d.width) { 112 this.colWidth[c] = d.width; 113 } 114 if (this.rowHeight[r] < d.height) { 115 this.rowHeight[r] = d.height; 116 } 117 } 118 } 119 int totalHeight = this.vGap * (nrows - 1); 120 for (int r = 0; r < nrows; r++) { 121 totalHeight = totalHeight + this.rowHeight[r]; 122 } 123 final int totalWidth = this.colWidth[0] + this.labelGap 124 + this.colWidth[1] + this.buttonGap + this.colWidth[2]; 125 return new Dimension( 126 insets.left + insets.right + totalWidth + this.labelGap 127 + this.buttonGap, 128 insets.top + insets.bottom + totalHeight + this.vGap 129 ); 130 } 131 132 } 133 134 /** 135 * Returns the minimum size using this layout manager. 136 * 137 * @param parent the parent. 138 * 139 * @return the minimum size using this layout manager. 140 */ minimumLayoutSize(final Container parent)141 public Dimension minimumLayoutSize(final Container parent) { 142 143 synchronized (parent.getTreeLock()) { 144 final Insets insets = parent.getInsets(); 145 final int ncomponents = parent.getComponentCount(); 146 final int nrows = ncomponents / COLUMNS; 147 for (int c = 0; c < COLUMNS; c++) { 148 for (int r = 0; r < nrows; r++) { 149 final Component component 150 = parent.getComponent(r * COLUMNS + c); 151 final Dimension d = component.getMinimumSize(); 152 if (this.colWidth[c] < d.width) { 153 this.colWidth[c] = d.width; 154 } 155 if (this.rowHeight[r] < d.height) { 156 this.rowHeight[r] = d.height; 157 } 158 } 159 } 160 int totalHeight = this.vGap * (nrows - 1); 161 for (int r = 0; r < nrows; r++) { 162 totalHeight = totalHeight + this.rowHeight[r]; 163 } 164 final int totalWidth = this.colWidth[0] + this.labelGap 165 + this.colWidth[1] + this.buttonGap + this.colWidth[2]; 166 return new Dimension( 167 insets.left + insets.right + totalWidth + this.labelGap 168 + this.buttonGap, 169 insets.top + insets.bottom + totalHeight + this.vGap 170 ); 171 } 172 173 } 174 175 /** 176 * Lays out the components. 177 * 178 * @param parent the parent. 179 */ layoutContainer(final Container parent)180 public void layoutContainer(final Container parent) { 181 182 synchronized (parent.getTreeLock()) { 183 final Insets insets = parent.getInsets(); 184 final int ncomponents = parent.getComponentCount(); 185 final int nrows = ncomponents / COLUMNS; 186 for (int c = 0; c < COLUMNS; c++) { 187 for (int r = 0; r < nrows; r++) { 188 final Component component 189 = parent.getComponent(r * COLUMNS + c); 190 final Dimension d = component.getPreferredSize(); 191 if (this.colWidth[c] < d.width) { 192 this.colWidth[c] = d.width; 193 } 194 if (this.rowHeight[r] < d.height) { 195 this.rowHeight[r] = d.height; 196 } 197 } 198 } 199 int totalHeight = this.vGap * (nrows - 1); 200 for (int r = 0; r < nrows; r++) { 201 totalHeight = totalHeight + this.rowHeight[r]; 202 } 203 final int totalWidth = this.colWidth[0] + this.colWidth[1] 204 + this.colWidth[2]; 205 206 // adjust the width of the second column to use up all of parent 207 final int available = parent.getWidth() - insets.left 208 - insets.right - this.labelGap - this.buttonGap; 209 this.colWidth[1] = this.colWidth[1] + (available - totalWidth); 210 211 // *** DO THE LAYOUT *** 212 int x = insets.left; 213 for (int c = 0; c < COLUMNS; c++) { 214 int y = insets.top; 215 for (int r = 0; r < nrows; r++) { 216 final int i = r * COLUMNS + c; 217 if (i < ncomponents) { 218 final Component component = parent.getComponent(i); 219 final Dimension d = component.getPreferredSize(); 220 final int h = d.height; 221 final int adjust = (this.rowHeight[r] - h) / 2; 222 parent.getComponent(i).setBounds(x, y + adjust, 223 this.colWidth[c], h); 224 } 225 y = y + this.rowHeight[r] + this.vGap; 226 } 227 x = x + this.colWidth[c]; 228 if (c == 0) { 229 x = x + this.labelGap; 230 } 231 if (c == 1) { 232 x = x + this.buttonGap; 233 } 234 } 235 236 } 237 238 } 239 240 /** 241 * Not used. 242 * 243 * @param comp the component. 244 */ addLayoutComponent(final Component comp)245 public void addLayoutComponent(final Component comp) { 246 // not used 247 } 248 249 /** 250 * Not used. 251 * 252 * @param comp the component. 253 */ removeLayoutComponent(final Component comp)254 public void removeLayoutComponent(final Component comp) { 255 // not used 256 } 257 258 /** 259 * Not used. 260 * 261 * @param name the component name. 262 * @param comp the component. 263 */ addLayoutComponent(final String name, final Component comp)264 public void addLayoutComponent(final String name, final Component comp) { 265 // not used 266 } 267 268 /** 269 * Not used. 270 * 271 * @param name the component name. 272 * @param comp the component. 273 */ removeLayoutComponent(final String name, final Component comp)274 public void removeLayoutComponent(final String name, final Component comp) { 275 // not used 276 } 277 278 } 279