001/* ======================================================================== 002 * JCommon : a free general purpose class library for the Java(tm) platform 003 * ======================================================================== 004 * 005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jcommon/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * -------------- 028 * LCBLayout.java 029 * -------------- 030 * (C) Copyright 2000-2005, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * $Id: LCBLayout.java,v 1.5 2005/11/16 15:58:40 taqua Exp $ 036 * 037 * Changes (from 26-Oct-2001) 038 * -------------------------- 039 * 26-Oct-2001 : Changed package to com.jrefinery.layout.* (DG); 040 * 10-Oct-2002 : Fixed errors reported by Checkstyle (DG); 041 */ 042 043package org.jfree.layout; 044 045import java.awt.Component; 046import java.awt.Container; 047import java.awt.Dimension; 048import java.awt.Insets; 049import java.awt.LayoutManager; 050import java.io.Serializable; 051 052/** 053 * Specialised layout manager for a grid of components. 054 * 055 * @author David Gilbert 056 */ 057public class LCBLayout implements LayoutManager, Serializable { 058 059 /** For serialization. */ 060 private static final long serialVersionUID = -2531780832406163833L; 061 062 /** A constant for the number of columns in the layout. */ 063 private static final int COLUMNS = 3; 064 065 /** Tracks the column widths. */ 066 private int[] colWidth; 067 068 /** Tracks the row heights. */ 069 private int[] rowHeight; 070 071 /** The gap between each label and component. */ 072 private int labelGap; 073 074 /** The gap between each component and button. */ 075 private int buttonGap; 076 077 /** The gap between rows. */ 078 private int vGap; 079 080 /** 081 * Creates a new LCBLayout with the specified maximum number of rows. 082 * 083 * @param maxrows the maximum number of rows. 084 */ 085 public LCBLayout(final int maxrows) { 086 this.labelGap = 10; 087 this.buttonGap = 6; 088 this.vGap = 2; 089 this.colWidth = new int[COLUMNS]; 090 this.rowHeight = new int[maxrows]; 091 } 092 093 /** 094 * Returns the preferred size using this layout manager. 095 * 096 * @param parent the parent. 097 * 098 * @return the preferred size using this layout manager. 099 */ 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 */ 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 */ 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 */ 245 public void addLayoutComponent(final Component comp) { 246 // not used 247 } 248 249 /** 250 * Not used. 251 * 252 * @param comp the component. 253 */ 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 */ 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 */ 274 public void removeLayoutComponent(final String name, final Component comp) { 275 // not used 276 } 277 278}