PageRenderTime 476ms CodeModel.GetById 211ms app.highlight 16ms RepoModel.GetById 246ms app.codeStats 0ms

/wicketwebbeans/src/main/java/com/googlecode/wicketwebbeans/containers/BeanGridPanel.java

http://wicket-web-beans.googlecode.com/
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}