/wicketwebbeans/src/main/java/com/googlecode/wicketwebbeans/containers/BeanGridPanel.java
Java | 228 lines | 141 code | 32 blank | 55 comment | 16 complexity | fb9039c0d81dda54d0925ecd33c6a262 MD5 | raw file
1/*--- 2 Copyright 2006-2007 Visual Systems Corporation. 3 http://www.vscorp.com 4 5 Licensed under the Apache License, Version 2.0 (the "License"); 6 you may not use this file except in compliance with the License. 7 You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11 Unless required by applicable law or agreed to in writing, software 12 distributed under the License is distributed on an "AS IS" BASIS, 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 See the License for the specific language governing permissions and 15 limitations under the License. 16---*/ 17package com.googlecode.wicketwebbeans.containers; 18 19import java.io.Serializable; 20import java.util.ArrayList; 21import java.util.List; 22 23 24import org.apache.wicket.AttributeModifier; 25import org.apache.wicket.Component; 26import org.apache.wicket.behavior.SimpleAttributeModifier; 27import org.apache.wicket.markup.ComponentTag; 28import org.apache.wicket.markup.html.form.Form; 29import org.apache.wicket.markup.html.list.ListItem; 30import org.apache.wicket.markup.html.list.ListView; 31import org.apache.wicket.markup.html.panel.Panel; 32import org.apache.wicket.model.IModel; 33import org.apache.wicket.model.Model; 34 35import com.googlecode.wicketwebbeans.actions.BeanActionButton; 36import com.googlecode.wicketwebbeans.fields.LabeledField; 37import com.googlecode.wicketwebbeans.fields.UnlabeledField; 38import com.googlecode.wicketwebbeans.model.BeanMetaData; 39import com.googlecode.wicketwebbeans.model.ElementMetaData; 40import com.googlecode.wicketwebbeans.model.TabMetaData; 41 42 43/** 44 * A panel for generically displaying Java Beans in a grid-style layout. 45 * The Bean config may specify the number of columns as "cols". The default is 3. 46 * Elements within the grid may specify a config parameter of "colspan" which indicates the 47 * number of columns to span in the grid. 48 * These parameters, along with EMPTY fields, allow for flexible layout. 49 * 50 * @author Dan Syrstad 51 */ 52public class BeanGridPanel extends Panel 53{ 54 public static final String PARAM_COLSPAN = "colspan"; 55 public static final String PARAM_COLS = "cols"; 56 57 private static final long serialVersionUID = -2149828837634944417L; 58 59 private Object bean; 60 private BeanMetaData beanMetaData; 61 private TabMetaData tabMetaData; 62 private boolean showLabels; 63 private int columns; 64 65 /** 66 * Construct a new BeanGridPanel. 67 * 68 * @param id the Wicket id for the panel. 69 * @param bean the bean to be displayed. This may be an IModel or regular bean object. 70 * @param beanMetaData the meta data for the bean 71 */ 72 public BeanGridPanel(String id, final Object bean, final BeanMetaData beanMetaData) 73 { 74 this(id, bean, beanMetaData, null); 75 } 76 77 /** 78 * Construct a new BeanGridPanel. 79 * 80 * @param id the Wicket id for the panel. 81 * @param bean the bean to be displayed. This may be an IModel or regular bean object. 82 * @param beanMetaData the meta data for the bean 83 * @param groupMetaData the tab to be displayed. If this is null, all displayed properties 84 * for the bean will be displayed. 85 */ 86 public BeanGridPanel(String id, final Object bean, final BeanMetaData beanMetaData, TabMetaData groupMetaData) 87 { 88 this(id, bean, beanMetaData, groupMetaData, true); 89 } 90 91 /** 92 * Construct a new BeanGridPanel. 93 * 94 * @param id the Wicket id for the panel. 95 * @param bean the bean to be displayed. This may be an IModel or regular bean object. 96 * @param beanMetaData the meta data for the bean 97 * @param tabMetaData the tab to be displayed. If this is null, all displayed properties 98 * for the bean will be displayed. 99 * @param showLabels if true, property labels will be displayed, otherwise they won't. 100 */ 101 public BeanGridPanel(String id, final Object bean, final BeanMetaData beanMetaData, TabMetaData tabMetaData, 102 final boolean showLabels) 103 { 104 super(id); 105 106 this.bean = bean; 107 this.beanMetaData = beanMetaData; 108 this.tabMetaData = tabMetaData; 109 this.showLabels = showLabels; 110 111 beanMetaData.applyCss(bean, beanMetaData, this); 112 113 List<ElementMetaData> displayedProperties; 114 if (tabMetaData == null) { 115 displayedProperties = beanMetaData.getDisplayedElements(); 116 } 117 else { 118 displayedProperties = beanMetaData.getTabElements(tabMetaData); 119 } 120 121 // Get Number of rows from config 122 //Properties config = beanMetaData.getParameters(); 123 columns = beanMetaData.getIntParameter(PARAM_COLS, 3); 124 if (columns < 1) { 125 throw new RuntimeException("Invalid columns config value: " + columns); 126 } 127 128 // Break out the rows and columns ahead of time. 129 List<List<ElementMetaData>> rowsAndCols = new ArrayList<List<ElementMetaData>>(); 130 int colPos = 0; 131 List<ElementMetaData> currRow = null; 132 for (ElementMetaData element : displayedProperties) { 133 int colspan = element.getIntParameter(PARAM_COLSPAN, 1); 134 if (colspan < 1 || colspan > columns) { 135 throw new RuntimeException("Invalid colspan parameter value: " + colspan); 136 } 137 138 // If colspan > number of columns left, start a new row. 139 if ((colPos + colspan) > columns) { 140 colPos = 0; 141 } 142 143 if (colPos == 0) { 144 currRow = new ArrayList<ElementMetaData>(); 145 rowsAndCols.add(currRow); 146 } 147 148 currRow.add(element); 149 colPos += colspan; 150 if (colPos >= columns) { 151 colPos = 0; 152 } 153 } 154 155 Model propModel = new Model<Serializable>((Serializable) rowsAndCols); 156 add( new RowListView("r", propModel) ); 157 } 158 159 @Override 160 public void detachModels() 161 { 162 super.detachModels(); 163 if (bean instanceof IModel) { 164 ((IModel)bean).detach(); 165 } 166 } 167 168 @Override 169 protected void onComponentTag(ComponentTag tag) 170 { 171 super.onComponentTag(tag); 172 beanMetaData.warnIfAnyParameterNotConsumed(tabMetaData); 173 } 174 175 private final class RowListView extends ListView 176 { 177 private static final long serialVersionUID = 1L; 178 179 RowListView(String id, IModel model) 180 { 181 super(id, model); 182 } 183 184 protected void populateItem(ListItem item) 185 { 186 List<ElementMetaData> columns = (List<ElementMetaData>)item.getModelObject(); 187 188 item.add( new ColListView("c", new Model((Serializable)columns))); 189 } 190 } 191 192 private final class ColListView extends ListView 193 { 194 private static final long serialVersionUID = 1L; 195 196 ColListView(String id, IModel model) 197 { 198 super(id, model); 199 } 200 201 protected void populateItem(ListItem item) 202 { 203 ElementMetaData element = (ElementMetaData) item.getModelObject(); 204 int colspan = element.getIntParameter(PARAM_COLSPAN, 1); 205 206 Component component; 207 if (element.isAction()) { 208 Form form = findParent(Form.class); 209 component = new BeanActionButton("c", element, form, bean); 210 item.add( new SimpleAttributeModifier("class", "beanActionButtonCell") ); 211 } 212 else { 213 component = beanMetaData.getComponentRegistry().getComponent(bean, "c", element); 214 if (!(component instanceof UnlabeledField) && showLabels) { 215 component = new LabeledField("c", element.getLabelComponent("l"), component); 216 } 217 } 218 219 beanMetaData.applyCss(bean, element, component); 220 221 item.add( new AttributeModifier(PARAM_COLSPAN, true, new Model<String>(String.valueOf(colspan))) ); 222 int pct100 = (colspan * 10000) / columns; 223 String width = "width: " + (pct100 / 100) + "." + (pct100 % 100) + "%;"; 224 item.add( new AttributeModifier("style", true, new Model<String>(width)) ); 225 item.add(component); 226 } 227 } 228}