package org.openswing.swing.table.columns.client; import java.lang.reflect.*; import java.math.*; import java.sql.*; import java.util.*; import java.util.Date; import java.awt.event.*; import javax.swing.table.*; import org.openswing.swing.items.client.*; import org.openswing.swing.logger.client.*; import org.openswing.swing.message.receive.java.*; import org.openswing.swing.table.client.*; import org.openswing.swing.table.editors.client.*; import org.openswing.swing.table.renderers.client.*; import java.awt.ComponentOrientation; import org.openswing.swing.util.client.ClientSettings; /** * <p>Title: OpenSwing Framework</p> * <p>Description: Column of type combo-box: it contains a combo box showing a list of value objects. * Its items are retrieved through the combo box controller, that returns a list of value object; * for each value object there exists a row in the combo box: v.o. attributes can be mapped as columns in an item.</p> * <p>Copyright: Copyright (C) 2006 Mauro Carniel</p> * * <p> This file is part of OpenSwing Framework. * This library is free software; you can redistribute it and/or * modify it under the terms of the (LGPL) Lesser General Public * License as published by the Free Software Foundation; * * GNU LESSER GENERAL PUBLIC LICENSE * Version 2.1, February 1999 * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The author may be contacted at: * maurocarniel@tin.it</p> * * @author Mauro Carniel * @version 1.0 */ public class ComboVOColumn extends Column { /** combo item listeners */ private ArrayList itemListeners = new ArrayList(); /** define if in insert mode combo box has no item selected; default value: <code>false</code> i.e. the first item is pre-selected */ private boolean nullAsDefaultValue = false; /** mapping between items v.o. attributes and items container v.o. attributes */ private ItemsMapper itemsMapper = new ItemsMapper(); /** items data source */ private ItemsDataLocator itemsDataLocator = null; /** items value object */ private ValueObject itemsVO = null; /** columns associated to lookup grid */ private Column[] colProperties = new Column[0]; /** flag used to set visibility on all columns of lookup grid; default "false" */ private boolean allColumnVisible = false; /** default preferredWidth for all columns of lookup grid; default 100 pixels */ private int allColumnPreferredWidth = 100; /** collection of pairs <v.o. attribute name,Method object, related to the attribute getter method> */ private Hashtable getters = new Hashtable(); /** component left margin, with respect to component container; defaut value: 2 */ private int leftMargin = 2; /** component right margin, with respect to component container; defaut value: 0 */ private int rightMargin = 0; /** component top margin, with respect to component container; defaut value: 0 */ private int topMargin = 0; /** component bottom margin, with respect to component container; defaut value: 0 */ private int bottomMargin = 0; /** attribute name in the combo-box v.o. that identify the attribute name in the v.o. of the combo-box container; as default value this attribute is null; null means that "attributeName" property will be used to identify the v.o. in the combo-box, i.e. the attribute names in the combo-box v.o. and in the container v.o. must have the same name */ private String foreignKeyAttributeName; /** component orientation */ private ComponentOrientation orientation = ClientSettings.TEXT_ORIENTATION; /** ComboVOTableCellRenderer (cell renderer), one for each grid controller (top locked rows, bottom locked rows, etc.) */ private HashMap renderers = new HashMap(); /** ComboBoxVOCellEditor (cell editor), one for each grid controller (top locked rows, bottom locked rows, etc.) */ private HashMap editors = new HashMap(); public ComboVOColumn() { } /** * @return column type */ public int getColumnType() { return TYPE_COMBO_VO; } /** * Add an ItemListener to the combo. * @param listener ItemListener to add */ public final void addItemListener(ItemListener listener) { itemListeners.add(listener); } /** * Remove an ItemListener from the combo. * @param listener ItemListener to remove */ public final void removeItemListener(ItemListener listener) { itemListeners.remove(listener); } /** * @return ItemListener objects */ public final ArrayList getItemListeners() { return itemListeners; } /** * @return define if in insert mode combo box has no item selected */ public final boolean isNullAsDefaultValue() { return nullAsDefaultValue; } /** * Define if in insert mode combo box has no item selected. * @param nullAsDefaultValue define if in insert mode combo box has no item selected */ public final void setNullAsDefaultValue(boolean nullAsDefaultValue) { this.nullAsDefaultValue = nullAsDefaultValue; } /** * Set column visibility in the combo box grid frame. * @param comboAttributeName attribute name that identifies the item column * @param visible column visibility state */ public final void setVisibleColumn(String comboAttributeName, boolean visible) { try { Column infoTemp; int visibleIndex = -1; int index = -1; for (int i = 0; i < colProperties.length; i++) { if (colProperties[i].isVisible()) visibleIndex = i; if (colProperties[i].getColumnName().equals(comboAttributeName)) { colProperties[i].setColumnVisible(visible); colProperties[i].setColumnSelectable(visible); index = i; break; } } if (visible) { if (visibleIndex==-1) visibleIndex=0; else if ((visibleIndex-1) < colProperties.length) visibleIndex++; if ( (index > -1) && (index != visibleIndex)) { infoTemp = colProperties[index]; colProperties[index] = colProperties[visibleIndex]; colProperties[visibleIndex] = infoTemp; } } } catch (Exception ex) { ex.printStackTrace(); } } /** * Add a link from an attribute of the combo box v.o. to an attribute of the combo box container v.o. * @param comboAttributeName attribute of the combo box v.o. * @param parentAttributeName attribute of the combo box container v.o. */ public final void addCombo2ParentLink(String comboAttributeName,String parentAttributeName) { itemsMapper.addItem2ParentLink(comboAttributeName,parentAttributeName); } /** * Add a link from the whole combo box value object to an equivalent inner v.o. included in the container v.o. * @param parentAttributeName attribute of the combo box container v.o., related to an inner v.o. having the same type of the combo box v.o. */ public final void addCombo2ParentLink(String parentAttributeName) { itemsMapper.addItem2ParentLink("",parentAttributeName); } /** * @return combo box data locator */ public final ItemsDataLocator getComboDataLocator() { return itemsDataLocator; } /** * Set combo box data locator. * @param comboDataLocator combo box data locator */ public final void setComboDataLocator(ItemsDataLocator comboDataLocator) { this.itemsDataLocator = comboDataLocator; } /** * Set value object class name associated to the combo box: this method calls initItemsVO method. * @param itemsValeuObjectClassName value object class name associated to the combo box */ public final void setComboValueObjectClassName(String comboValueObjectClassName) { initItemsVO(comboValueObjectClassName); } /** * Method called by setComboValueObjectClassName: * - it creates an empty combo v.o * - it initializes combo column properties. * @param itemsValueObjectClassName combo value object class name */ private void initItemsVO(String itemsValueObjectClassName) { try { this.itemsVO = (ValueObject) Class.forName(itemsValueObjectClassName).getConstructor(new Class[0]).newInstance(new Object[0]); Method[] methods = itemsVO.getClass().getMethods(); int count = 0; for(int i=0;i<methods.length;i++) { if (methods[i].getName().startsWith("get") && methods[i].getParameterTypes().length==0 && ( methods[i].getReturnType().equals(String.class) || methods[i].getReturnType().equals(java.math.BigDecimal.class) || methods[i].getReturnType().equals(java.util.Date.class) || methods[i].getReturnType().equals(java.sql.Date.class) || methods[i].getReturnType().equals(java.sql.Timestamp.class) || methods[i].getReturnType().equals(Integer.class) || methods[i].getReturnType().equals(Long.class) || methods[i].getReturnType().equals(Short.class) || methods[i].getReturnType().equals(Double.class) || methods[i].getReturnType().equals(Float.class) || methods[i].getReturnType().equals(Integer.TYPE) || methods[i].getReturnType().equals(Long.TYPE) || methods[i].getReturnType().equals(Short.TYPE) || methods[i].getReturnType().equals(Double.TYPE) || methods[i].getReturnType().equals(Float.TYPE) || methods[i].getReturnType().equals(Boolean.class)) ) count++; } String[] attributeNames = new String[count]; this.colProperties = new Column[count]; count = 0; Class colType = null; for(int i=0;i<methods.length;i++) { if (methods[i].getName().startsWith("get") && methods[i].getParameterTypes().length==0 && ( methods[i].getReturnType().equals(String.class) || methods[i].getReturnType().equals(java.math.BigDecimal.class) || methods[i].getReturnType().equals(java.util.Date.class) || methods[i].getReturnType().equals(java.sql.Date.class) || methods[i].getReturnType().equals(java.sql.Timestamp.class) || methods[i].getReturnType().equals(Integer.class) || methods[i].getReturnType().equals(Long.class) || methods[i].getReturnType().equals(Short.class) || methods[i].getReturnType().equals(Double.class) || methods[i].getReturnType().equals(Float.class) || methods[i].getReturnType().equals(Integer.TYPE) || methods[i].getReturnType().equals(Long.TYPE) || methods[i].getReturnType().equals(Short.TYPE) || methods[i].getReturnType().equals(Double.TYPE) || methods[i].getReturnType().equals(Float.TYPE) || methods[i].getReturnType().equals(Boolean.class)) ) { attributeNames[count] = methods[i].getName().substring(3); if (attributeNames[count].length()>1) attributeNames[count] = attributeNames[count].substring(0,1).toLowerCase()+attributeNames[count].substring(1); colType = methods[i].getReturnType(); if (colType.equals(String.class)) colProperties[count] = new TextColumn(); else if (colType.equals(Integer.class) || colType.equals(Long.class) || colType.equals(Short.class) || colType.equals(Integer.TYPE) || colType.equals(Long.TYPE) || colType.equals(Short.TYPE)) colProperties[count] = new IntegerColumn(); else if (colType.equals(BigDecimal.class) || colType.equals(Double.class) || colType.equals(Float.class) || colType.equals(Double.TYPE) || colType.equals(Float.TYPE)) colProperties[count] = new DecimalColumn(); else if (colType.equals(Boolean.class)) colProperties[count] = new CheckBoxColumn(); else if (colType.equals(Date.class)) colProperties[count] = new DateColumn(); else if (colType.equals(java.sql.Date.class)) colProperties[count] = new DateColumn(); else if (colType.equals(Timestamp.class)) colProperties[count] = new DateColumn(); colProperties[count].setColumnName(attributeNames[count]); if (colProperties[count].getHeaderColumnName().equals("columnname")) colProperties[count].setHeaderColumnName(String.valueOf(attributeNames[count].charAt(0)).toUpperCase()+attributeNames[count].substring(1)); colProperties[count].setColumnVisible(this.allColumnVisible); colProperties[count].setPreferredWidth(this.allColumnPreferredWidth); getters.put( colProperties[count].getColumnName(), methods[i] ); count++; } } } catch (Exception ex) { ex.printStackTrace(); this.itemsVO = null; } catch (Error er) { er.printStackTrace(); this.itemsVO = null; } } /** * @return columns visibility */ public final boolean isAllColumnVisible() { return this.allColumnVisible; } /** * Set column visibility for the whole columns of the items grid frame. * @param visible columns visibility */ public final void setAllColumnVisible(boolean visible) { this.allColumnVisible = visible; for(int i=0; i<colProperties.length; i++) { colProperties[i].setColumnVisible(visible); colProperties[i].setColumnSelectable(visible); } } /** * @return columns width */ public final int getAllColumnPreferredWidth() { return this.allColumnPreferredWidth; } /** * Set columns width for the whole columns of the items grid frame. * @param preferredWidth columns width */ public final void setAllColumnPreferredWidth(int preferredWidth) { this.allColumnPreferredWidth = preferredWidth; for(int i=0; i<colProperties.length; i++) colProperties[i].setPreferredWidth(preferredWidth); } /** * Set column width in the items grid frame. * @param itemsAttributeName attribute name that identifies the grid column * @param preferredWidth column width */ public final void setPreferredWidthColumn(String itemsAttributeName,int preferredWidth) { for(int i=0;i<colProperties.length;i++) if (colProperties[i].getColumnName().equals(itemsAttributeName)) { colProperties[i].setPreferredWidth(preferredWidth); return; } Logger.error(this.getClass().getName(),"setPreferredWidthColumn","The attribute '"+(itemsAttributeName==null?"null":"'"+itemsAttributeName+"'")+"' does not exist.",null); } public Column[] getColProperties() { return colProperties; } public Hashtable getGetters() { return getters; } public ValueObject getItemsVO() { return itemsVO; } public ItemsMapper getItemsMapper() { return itemsMapper; } /** * @return component bottom margin, with respect to component container */ public final int getBottomMargin() { return bottomMargin; } /** * @return component left margin, with respect to component container */ public final int getLeftMargin() { return leftMargin; } /** * @return component right margin, with respect to component container */ public final int getRightMargin() { return rightMargin; } /** * @return component top margin, with respect to component container */ public final int getTopMargin() { return topMargin; } /** * Set component top margin, with respect to component container. * @param topMargin component top margin */ public final void setTopMargin(int topMargin) { this.topMargin = topMargin; } /** * Set component right margin, with respect to component container. * @param rightMargin component right margin */ public final void setRightMargin(int rightMargin) { this.rightMargin = rightMargin; } /** * Set component left margin, with respect to component container. * @param leftMargin component left margin */ public final void setLeftMargin(int leftMargin) { this.leftMargin = leftMargin; } /** * Set component bottom margin, with respect to component container. * @param bottomMargin component bottom margin */ public final void setBottomMargin(int bottomMargin) { this.bottomMargin = bottomMargin; } /** * @return attribute name in the combo-box v.o. that identify the attribute name in the v.o. of the combo-box container */ public final String getForeignKeyAttributeName() { return foreignKeyAttributeName; } /** * Set the attribute name in the combo-box v.o. that identify the attribute name in the v.o. of the combo-box container. * As default value this attribute is null. * Null means that "attributeName" property will be used to identify the v.o. in the combo-box, i.e. the attribute names in the combo-box v.o. and in the container v.o. must have the same name. * @param foreignKeyAttributeName String */ public final void setForeignKeyAttributeName(String foreignKeyAttributeName) { this.foreignKeyAttributeName = foreignKeyAttributeName; } /** * Method used to reload items in combo-box. */ public final void reloadItems() { ComboVOTableCellRenderer renderer = null; ComboBoxVOCellEditor editor = null; Iterator it = renderers.values().iterator(); while(it.hasNext()) { renderer = (ComboVOTableCellRenderer)it.next(); renderer.reloadItems(); } it = editors.values().iterator(); while(it.hasNext()) { editor = (ComboBoxVOCellEditor)it.next(); editor.reloadItems(); } } /** * Set the component orientation: from left to right or from right to left. * @param orientation component orientation */ public final void setTextOrientation(ComponentOrientation orientation) { this.orientation = orientation; } /** * @return component orientation */ public final ComponentOrientation getTextOrientation() { return orientation; } /** * @return TableCellRenderer for this column */ public final TableCellRenderer getCellRenderer(GridController tableContainer,Grids grids) { ComboVOTableCellRenderer renderer = (ComboVOTableCellRenderer)renderers.get(tableContainer.toString()); if (renderer==null) { renderer = new ComboVOTableCellRenderer( getComboDataLocator(), getColumnName(), getItemsVO(), getColProperties(), isAllColumnVisible(), getAllColumnPreferredWidth(), getGetters(), tableContainer, leftMargin, rightMargin, topMargin, bottomMargin, getTextOrientation(), getForeignKeyAttributeName() ); renderers.put(tableContainer.toString(),renderer); } return renderer; } /** * @return TableCellEditor for this column */ public final TableCellEditor getCellEditor(GridController tableContainer,Grids grids) { ComboBoxVOCellEditor editor = (ComboBoxVOCellEditor)editors.get(tableContainer.toString()); if (editor==null) { editor = new ComboBoxVOCellEditor( getItemsMapper(), getComboDataLocator(), getColumnName(), getItemsVO(), getColProperties(), isAllColumnVisible(), getAllColumnPreferredWidth(), getGetters(), isColumnRequired(), getItemListeners(), getForeignKeyAttributeName(), leftMargin, rightMargin, topMargin, bottomMargin, getTextOrientation() ); editors.put(tableContainer.toString(),editor); } return editor; } }