001 /* JAPI - (Yet another (hopefully) useful) Java API 002 * 003 * Copyright (C) 2004-2006 Christian Hujer 004 * 005 * This program is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU General Public License as 007 * published by the Free Software Foundation; either version 2 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 * 02111-1307, USA. 019 */ 020 021 package net.sf.japi.swing; 022 023 import java.awt.Dimension; 024 import java.awt.Insets; 025 import java.awt.Component; 026 import java.awt.Container; 027 import java.awt.LayoutManager; 028 import org.jetbrains.annotations.NotNull; 029 import org.jetbrains.annotations.Nullable; 030 031 /** Layout similar to FlowLayout, but using columns (vertical layout) instead of rows (horizontal layout). 032 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a> 033 */ 034 @SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "FieldAccessedSynchronizedAndUnsynchronized"}) 035 public class ColumnLayout implements LayoutManager { 036 037 /** Horizontal Gap. */ 038 private int hgap = 4; 039 040 /** Vertical Gap. */ 041 private int vgap = 4; 042 043 /** Create a ColumnLayout with default gaps (4, 4). */ 044 public ColumnLayout() { 045 } 046 047 /** Create a ColumnLayout with defined gaps. 048 * @param hgap horizontal gap 049 * @param vgap vertical gap 050 */ 051 public ColumnLayout(final int hgap, final int vgap) { 052 this.hgap = hgap; 053 this.vgap = vgap; 054 } 055 056 /** Returns horizontal Gap. 057 * @return horizontal Gap. 058 */ 059 public int getHgap() { 060 return hgap; 061 } 062 063 /** Sets horizontal Gap. 064 * @param hgap horizontal Gap. 065 */ 066 public void setHgap(final int hgap) { 067 this.hgap = hgap; 068 } 069 070 /** Returns vertical Gap. 071 * @return vertical Gap. 072 */ 073 public int getVgap() { 074 return vgap; 075 } 076 077 /** Sets vertical Gap. 078 * @param vgap vertical Gap. 079 */ 080 public void setVgap(final int vgap) { 081 this.vgap = vgap; 082 } 083 084 /** {@inheritDoc} */ 085 public void addLayoutComponent(@Nullable final String name, @Nullable final Component comp) { 086 // Superfluous 087 } 088 089 /** {@inheritDoc} */ 090 public void removeLayoutComponent(@Nullable final Component comp) { 091 // Superfluous 092 } 093 094 /** {@inheritDoc} */ 095 @NotNull public Dimension preferredLayoutSize(@NotNull final Container parent) { 096 synchronized (parent.getTreeLock()) { 097 final Dimension preferredLayoutSize = new Dimension(); 098 final int nmembers = parent.getComponentCount(); 099 for (int i = 0; i < nmembers; i++) { 100 final Component comp = parent.getComponent(i); 101 if (comp.isVisible()) { 102 final Dimension dim = comp.getPreferredSize(); 103 preferredLayoutSize.width = Math.max(preferredLayoutSize.width, dim.width); 104 if (i > 0) { 105 preferredLayoutSize.height += vgap; 106 } 107 preferredLayoutSize.height += dim.height; 108 } 109 } 110 final Insets insets = parent.getInsets(); 111 preferredLayoutSize.width += insets.left + insets.right + (hgap << 1); 112 preferredLayoutSize.height += insets.top + insets.bottom + (vgap << 1); 113 return preferredLayoutSize; 114 } 115 } 116 117 /** {@inheritDoc} */ 118 @NotNull public Dimension minimumLayoutSize(@NotNull final Container parent) { 119 synchronized (parent.getTreeLock()) { 120 final Dimension minimumLayoutSize = new Dimension(); 121 final int nmembers = parent.getComponentCount(); 122 for (int i = 0; i < nmembers; i++) { 123 final Component comp = parent.getComponent(i); 124 if (comp.isVisible()) { 125 final Dimension dim = comp.getMinimumSize(); 126 minimumLayoutSize.width = Math.max(minimumLayoutSize.width, dim.width); 127 if (i > 0) { 128 minimumLayoutSize.height += vgap; 129 } 130 minimumLayoutSize.height += dim.height; 131 } 132 } 133 final Insets insets = parent.getInsets(); 134 minimumLayoutSize.width += insets.left + insets.right + (hgap << 1); 135 minimumLayoutSize.height += insets.top + insets.bottom + (vgap << 1); 136 return minimumLayoutSize; 137 } 138 } 139 140 /** {@inheritDoc} */ 141 public void layoutContainer(@NotNull final Container parent) { 142 synchronized (parent.getTreeLock()) { 143 final Insets insets = parent.getInsets(); 144 final int nmembers = parent.getComponentCount(); 145 final int maxheight = parent.getHeight() - (insets.left + insets.right + (vgap << 1)); 146 int maxwidth = 0; 147 int y = 0; 148 int x = insets.left + hgap; 149 for (int i = 0; i < nmembers; i++) { 150 final Component comp = parent.getComponent(i); 151 if (comp.isVisible()) { 152 final Dimension dim = comp.getPreferredSize(); 153 comp.setSize(dim); 154 if (y + vgap + comp.getHeight() > maxheight) { 155 y = 0; 156 x += maxwidth + hgap; 157 maxwidth = 0; 158 } 159 maxwidth = comp.getWidth() > maxwidth ? comp.getWidth() : maxwidth; 160 y += vgap; 161 comp.setLocation(x, y); 162 y += comp.getHeight(); 163 } 164 } 165 } 166 } 167 168 } // class ColumnLayout