001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 */ 028 029package org.jfree.chart.ui; 030 031import java.awt.Component; 032import java.awt.Container; 033import java.awt.Dimension; 034import java.awt.Insets; 035import java.awt.LayoutManager; 036import java.io.Serializable; 037 038/** 039 * Specialised layout manager for a grid of components. 040 */ 041public class LCBLayout implements LayoutManager, Serializable { 042 043 /** For serialization. */ 044 private static final long serialVersionUID = -2531780832406163833L; 045 046 /** A constant for the number of columns in the layout. */ 047 private static final int COLUMNS = 3; 048 049 /** Tracks the column widths. */ 050 private int[] colWidth; 051 052 /** Tracks the row heights. */ 053 private int[] rowHeight; 054 055 /** The gap between each label and component. */ 056 private int labelGap; 057 058 /** The gap between each component and button. */ 059 private int buttonGap; 060 061 /** The gap between rows. */ 062 private int vGap; 063 064 /** 065 * Creates a new LCBLayout with the specified maximum number of rows. 066 * 067 * @param maxrows the maximum number of rows. 068 */ 069 public LCBLayout(int maxrows) { 070 this.labelGap = 10; 071 this.buttonGap = 6; 072 this.vGap = 2; 073 this.colWidth = new int[COLUMNS]; 074 this.rowHeight = new int[maxrows]; 075 } 076 077 /** 078 * Returns the preferred size using this layout manager. 079 * 080 * @param parent the parent. 081 * 082 * @return the preferred size using this layout manager. 083 */ 084 @Override 085 public Dimension preferredLayoutSize(Container parent) { 086 087 synchronized (parent.getTreeLock()) { 088 Insets insets = parent.getInsets(); 089 int ncomponents = parent.getComponentCount(); 090 int nrows = ncomponents / COLUMNS; 091 for (int c = 0; c < COLUMNS; c++) { 092 for (int r = 0; r < nrows; r++) { 093 Component component = parent.getComponent(r * COLUMNS + c); 094 Dimension d = component.getPreferredSize(); 095 if (this.colWidth[c] < d.width) { 096 this.colWidth[c] = d.width; 097 } 098 if (this.rowHeight[r] < d.height) { 099 this.rowHeight[r] = d.height; 100 } 101 } 102 } 103 int totalHeight = this.vGap * (nrows - 1); 104 for (int r = 0; r < nrows; r++) { 105 totalHeight = totalHeight + this.rowHeight[r]; 106 } 107 int totalWidth = this.colWidth[0] + this.labelGap 108 + this.colWidth[1] + this.buttonGap + this.colWidth[2]; 109 return new Dimension( 110 insets.left + insets.right + totalWidth + this.labelGap 111 + this.buttonGap, 112 insets.top + insets.bottom + totalHeight + this.vGap 113 ); 114 } 115 116 } 117 118 /** 119 * Returns the minimum size using this layout manager. 120 * 121 * @param parent the parent. 122 * 123 * @return the minimum size using this layout manager. 124 */ 125 @Override 126 public Dimension minimumLayoutSize(Container parent) { 127 128 synchronized (parent.getTreeLock()) { 129 Insets insets = parent.getInsets(); 130 int ncomponents = parent.getComponentCount(); 131 int nrows = ncomponents / COLUMNS; 132 for (int c = 0; c < COLUMNS; c++) { 133 for (int r = 0; r < nrows; r++) { 134 Component component = parent.getComponent(r * COLUMNS + c); 135 Dimension d = component.getMinimumSize(); 136 if (this.colWidth[c] < d.width) { 137 this.colWidth[c] = d.width; 138 } 139 if (this.rowHeight[r] < d.height) { 140 this.rowHeight[r] = d.height; 141 } 142 } 143 } 144 int totalHeight = this.vGap * (nrows - 1); 145 for (int r = 0; r < nrows; r++) { 146 totalHeight = totalHeight + this.rowHeight[r]; 147 } 148 int totalWidth = this.colWidth[0] + this.labelGap 149 + this.colWidth[1] + this.buttonGap + this.colWidth[2]; 150 return new Dimension( 151 insets.left + insets.right + totalWidth + this.labelGap 152 + this.buttonGap, 153 insets.top + insets.bottom + totalHeight + this.vGap 154 ); 155 } 156 157 } 158 159 /** 160 * Lays out the components. 161 * 162 * @param parent the parent. 163 */ 164 @Override 165 public void layoutContainer(Container parent) { 166 167 synchronized (parent.getTreeLock()) { 168 Insets insets = parent.getInsets(); 169 int ncomponents = parent.getComponentCount(); 170 int nrows = ncomponents / COLUMNS; 171 for (int c = 0; c < COLUMNS; c++) { 172 for (int r = 0; r < nrows; r++) { 173 Component component = parent.getComponent(r * COLUMNS + c); 174 Dimension d = component.getPreferredSize(); 175 if (this.colWidth[c] < d.width) { 176 this.colWidth[c] = d.width; 177 } 178 if (this.rowHeight[r] < d.height) { 179 this.rowHeight[r] = d.height; 180 } 181 } 182 } 183 int totalHeight = this.vGap * (nrows - 1); 184 for (int r = 0; r < nrows; r++) { 185 totalHeight = totalHeight + this.rowHeight[r]; 186 } 187 int totalWidth = this.colWidth[0] + this.colWidth[1] 188 + this.colWidth[2]; 189 190 // adjust the width of the second column to use up all of parent 191 int available = parent.getWidth() - insets.left 192 - insets.right - this.labelGap - this.buttonGap; 193 this.colWidth[1] = this.colWidth[1] + (available - totalWidth); 194 195 // *** DO THE LAYOUT *** 196 int x = insets.left; 197 for (int c = 0; c < COLUMNS; c++) { 198 int y = insets.top; 199 for (int r = 0; r < nrows; r++) { 200 int i = r * COLUMNS + c; 201 if (i < ncomponents) { 202 Component component = parent.getComponent(i); 203 Dimension d = component.getPreferredSize(); 204 int h = d.height; 205 int adjust = (this.rowHeight[r] - h) / 2; 206 parent.getComponent(i).setBounds(x, y + adjust, 207 this.colWidth[c], h); 208 } 209 y = y + this.rowHeight[r] + this.vGap; 210 } 211 x = x + this.colWidth[c]; 212 if (c == 0) { 213 x = x + this.labelGap; 214 } 215 if (c == 1) { 216 x = x + this.buttonGap; 217 } 218 } 219 220 } 221 222 } 223 224 /** 225 * Not used. 226 * 227 * @param comp the component. 228 */ 229 public void addLayoutComponent(Component comp) { 230 // not used 231 } 232 233 /** 234 * Not used. 235 * 236 * @param comp the component. 237 */ 238 @Override 239 public void removeLayoutComponent(Component comp) { 240 // not used 241 } 242 243 /** 244 * Not used. 245 * 246 * @param name the component name. 247 * @param comp the component. 248 */ 249 @Override 250 public void addLayoutComponent(String name, Component comp) { 251 // not used 252 } 253 254 /** 255 * Not used. 256 * 257 * @param name the component name. 258 * @param comp the component. 259 */ 260 public void removeLayoutComponent(String name, Component comp) { 261 // not used 262 } 263 264}