/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.fib.model; import java.awt.Color; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Logger; import javax.swing.ListSelectionModel; import org.openflexo.antar.binding.BindingDefinition; import org.openflexo.antar.binding.BindingDefinition.BindingDefinitionType; import org.openflexo.antar.binding.BindingModel; import org.openflexo.antar.binding.BindingVariableImpl; import org.openflexo.antar.binding.ParameterizedTypeImpl; import org.openflexo.antar.binding.TypeUtils; import org.openflexo.antar.binding.WilcardTypeImpl; import org.openflexo.fib.controller.FIBTableDynamicModel; import org.openflexo.fib.model.FIBTableAction.FIBAddAction; import org.openflexo.fib.model.FIBTableAction.FIBCustomAction; import org.openflexo.fib.model.FIBTableAction.FIBRemoveAction; public class FIBTable extends FIBWidget implements FIBTableComponent /*implements DynamicAccess*/{ private static final Logger logger = Logger.getLogger(FIBTable.class.getPackage().getName()); private BindingDefinition SELECTED; public BindingDefinition getSelectedBindingDefinition() { if (SELECTED == null) { SELECTED = new BindingDefinition("selected", getIteratorClass(), BindingDefinitionType.GET_SET, false); } return SELECTED; } public static enum Parameters implements FIBModelAttribute { iteratorClass, visibleRowCount, rowHeight, createNewRowOnClick, autoSelectFirstRow, boundToSelectionManager, selectionMode, selected, columns, actions, showFooter, textSelectionColor, textNonSelectionColor, backgroundSelectionColor, backgroundSecondarySelectionColor, backgroundNonSelectionColor } public enum SelectionMode { SingleSelection { @Override public int getMode() { return ListSelectionModel.SINGLE_SELECTION; } }, SingleIntervalSelection { @Override public int getMode() { return ListSelectionModel.SINGLE_INTERVAL_SELECTION; } }, MultipleIntervalSelection { @Override public int getMode() { return ListSelectionModel.MULTIPLE_INTERVAL_SELECTION; } }; public abstract int getMode(); } private DataBinding selected; private Integer visibleRowCount; private Integer rowHeight; private boolean createNewRowOnClick = false; private boolean autoSelectFirstRow = false; private boolean boundToSelectionManager = false; private boolean showFooter = true; private SelectionMode selectionMode = SelectionMode.MultipleIntervalSelection; private Class iteratorClass; private List<FIBTableColumn> columns; private List<FIBTableAction> actions; private BindingModel tableBindingModel; private BindingModel actionBindingModel; private Color textSelectionColor; private Color textNonSelectionColor; private Color backgroundSelectionColor; private Color backgroundSecondarySelectionColor; private Color backgroundNonSelectionColor; public FIBTable() { columns = new ArrayList<FIBTableColumn>(); actions = new ArrayList<FIBTableAction>(); } @Override protected String getBaseName() { return "Table"; } public FIBTableColumn getColumnWithTitle(String title) { for (FIBTableColumn c : columns) { if (title.equals(c.getTitle())) { return c; } } return null; } @Override public List<FIBTableColumn> getColumns() { return columns; } public void setColumns(List<FIBTableColumn> columns) { this.columns = columns; } public void addToColumns(FIBTableColumn aColumn) { aColumn.setTable(this); columns.add(aColumn); setChanged(); notifyObservers(new FIBAddingNotification<FIBTableColumn>(Parameters.columns, aColumn)); } public void removeFromColumns(FIBTableColumn aColumn) { aColumn.setTable(null); columns.remove(aColumn); setChanged(); notifyObservers(new FIBRemovingNotification<FIBTableColumn>(Parameters.columns, aColumn)); } public List<FIBTableAction> getActions() { return actions; } public void setActions(List<FIBTableAction> actions) { this.actions = actions; } public void addToActions(FIBTableAction anAction) { logger.fine("Add to actions " + anAction); anAction.setTable(this); actions.add(anAction); setChanged(); notifyObservers(new FIBAddingNotification<FIBTableAction>(Parameters.actions, anAction)); } public void removeFromActions(FIBTableAction anAction) { anAction.setTable(null); actions.remove(anAction); setChanged(); notifyObservers(new FIBRemovingNotification<FIBTableAction>(Parameters.actions, anAction)); } @Override public BindingModel getTableBindingModel() { if (tableBindingModel == null) { createTableBindingModel(); } return tableBindingModel; } private void createTableBindingModel() { tableBindingModel = new BindingModel(getBindingModel()); tableBindingModel.addToBindingVariables(new BindingVariableImpl(this, "iterator", getIteratorClass())); // System.out.println("dataClass="+getDataClass()+" dataClassName="+dataClassName); // logger.info("******** Table: "+getName()+" Add BindingVariable: iterator type="+getIteratorClass()); } public BindingModel getActionBindingModel() { if (actionBindingModel == null) { createActionBindingModel(); } return actionBindingModel; } private void createActionBindingModel() { actionBindingModel = new BindingModel(getBindingModel()); actionBindingModel.addToBindingVariables(new BindingVariableImpl(this, "selected", getIteratorClass())); // System.out.println("dataClass="+getDataClass()+" dataClassName="+dataClassName); // logger.info("******** Table: "+getName()+" Add BindingVariable: iterator type="+getIteratorClass()); } @Override public void notifiedBindingModelRecreated() { super.notifiedBindingModelRecreated(); createTableBindingModel(); createActionBindingModel(); } public DataBinding getSelected() { if (selected == null) { selected = new DataBinding(this, Parameters.selected, getSelectedBindingDefinition()); } return selected; } public void setSelected(DataBinding selected) { selected.setOwner(this); selected.setBindingAttribute(Parameters.selected); selected.setBindingDefinition(getSelectedBindingDefinition()); this.selected = selected; } @Override public void finalizeDeserialization() { logger.fine("finalizeDeserialization() for FIBTable " + getName()); /*if (tableBindingModel == null)*/createTableBindingModel(); /*if (actionBindingModel == null)*/createActionBindingModel(); super.finalizeDeserialization(); for (FIBTableColumn column : getColumns()) { column.finalizeTableDeserialization(); } if (selected != null) { selected.finalizeDeserialization(); } } /*public boolean hasDynamicKeyValueProperty(String name) { if (name.equals("selected")) return getDataClass() != null; return false; } private DynamicKeyValueProperty SELECTED_DKVP; public DynamicKeyValueProperty getDynamicKeyValueProperty(String name) { if (name.equals("selected")) { if (SELECTED_DKVP == null) SELECTED_DKVP = new DynamicKeyValueProperty("selected", getClass(), getDataClass()); return SELECTED_DKVP; } return null; }*/ public Class getIteratorClass() { if (iteratorClass == null) { iteratorClass = Object.class; } return iteratorClass; } public void setIteratorClass(Class iteratorClass) { FIBAttributeNotification<Class> notification = requireChange(Parameters.iteratorClass, iteratorClass); if (notification != null) { this.iteratorClass = iteratorClass; createTableBindingModel(); createActionBindingModel(); hasChanged(notification); } } @Override public Type getDefaultDataClass() { Type[] args = new Type[1]; args[0] = new WilcardTypeImpl(getIteratorClass()); return new ParameterizedTypeImpl(Collection.class, args); } @Override public Type getDynamicAccessType() { Type[] args = new Type[2]; args[0] = getDataType(); args[1] = getIteratorClass(); return new ParameterizedTypeImpl(FIBTableDynamicModel.class, args); } @Override public Boolean getManageDynamicModel() { return true; } @Override public void notifyBindingChanged(DataBinding binding) { logger.fine("notifyBindingChanged with " + binding); if (binding == getData()) { if (getData() != null && getData().getBinding() != null) { Type accessedType = getData().getBinding().getAccessedType(); if (accessedType instanceof ParameterizedType && ((ParameterizedType) accessedType).getActualTypeArguments().length > 0) { Class newIteratorClass = TypeUtils.getBaseClass(((ParameterizedType) accessedType).getActualTypeArguments()[0]); if (getIteratorClass() == null || !TypeUtils.isClassAncestorOf(newIteratorClass, getIteratorClass())) { setIteratorClass(newIteratorClass); } } } } } /*public String getIteratorClassName() { return iteratorClassName; } public void setIteratorClassName(String iteratorClassName) { FIBAttributeNotification<String> notification = requireChange( Parameters.iteratorClassName, iteratorClassName); if (notification != null) { this.iteratorClassName = iteratorClassName; iteratorClass = null; createTableBindingModel(); hasChanged(notification); } }*/ public boolean getAutoSelectFirstRow() { return autoSelectFirstRow; } public void setAutoSelectFirstRow(boolean autoSelectFirstRow) { FIBAttributeNotification<Boolean> notification = requireChange(Parameters.autoSelectFirstRow, autoSelectFirstRow); if (notification != null) { this.autoSelectFirstRow = autoSelectFirstRow; hasChanged(notification); } } public Integer getVisibleRowCount() { return visibleRowCount; } public void setVisibleRowCount(Integer visibleRowCount) { FIBAttributeNotification<Integer> notification = requireChange(Parameters.visibleRowCount, visibleRowCount); if (notification != null) { this.visibleRowCount = visibleRowCount; hasChanged(notification); } } public Integer getRowHeight() { return rowHeight; } public void setRowHeight(Integer rowHeight) { FIBAttributeNotification<Integer> notification = requireChange(Parameters.rowHeight, rowHeight); if (notification != null) { this.rowHeight = rowHeight; hasChanged(notification); } } public boolean getCreateNewRowOnClick() { return createNewRowOnClick; } public void setCreateNewRowOnClick(boolean createNewRowOnClick) { FIBAttributeNotification<Boolean> notification = requireChange(Parameters.createNewRowOnClick, createNewRowOnClick); if (notification != null) { this.createNewRowOnClick = createNewRowOnClick; hasChanged(notification); } } public boolean getShowFooter() { return showFooter; } public void setShowFooter(boolean showFooter) { FIBAttributeNotification<Boolean> notification = requireChange(Parameters.showFooter, showFooter); if (notification != null) { this.showFooter = showFooter; hasChanged(notification); } } public boolean getBoundToSelectionManager() { return boundToSelectionManager; } public void setBoundToSelectionManager(boolean boundToSelectionManager) { FIBAttributeNotification<Boolean> notification = requireChange(Parameters.boundToSelectionManager, boundToSelectionManager); if (notification != null) { this.boundToSelectionManager = boundToSelectionManager; hasChanged(notification); } } public FIBAddAction createAddAction() { FIBAddAction newAction = new FIBAddAction(); newAction.setName("add_action"); addToActions(newAction); return newAction; } public FIBRemoveAction createRemoveAction() { FIBRemoveAction newAction = new FIBRemoveAction(); newAction.setName("delete_action"); addToActions(newAction); return newAction; } public FIBCustomAction createCustomAction() { FIBCustomAction newAction = new FIBCustomAction(); newAction.setName("custom_action"); addToActions(newAction); return newAction; } public FIBTableAction deleteAction(FIBTableAction actionToDelete) { logger.info("Called deleteAction() with " + actionToDelete); removeFromActions(actionToDelete); return actionToDelete; } public FIBLabelColumn createLabelColumn() { FIBLabelColumn newColumn = new FIBLabelColumn(); newColumn.setName("label"); newColumn.setTitle("label"); addToColumns(newColumn); return newColumn; } public FIBTextFieldColumn createTextFieldColumn() { FIBTextFieldColumn newColumn = new FIBTextFieldColumn(); newColumn.setName("textfield"); newColumn.setTitle("textfield"); addToColumns(newColumn); return newColumn; } public FIBCheckBoxColumn createCheckBoxColumn() { FIBCheckBoxColumn newColumn = new FIBCheckBoxColumn(); newColumn.setName("checkbox"); newColumn.setTitle("checkbox"); addToColumns(newColumn); return newColumn; } public FIBDropDownColumn createDropDownColumn() { FIBDropDownColumn newColumn = new FIBDropDownColumn(); newColumn.setName("dropdown"); newColumn.setTitle("dropdown"); addToColumns(newColumn); return newColumn; } public FIBNumberColumn createNumberColumn() { FIBNumberColumn newColumn = new FIBNumberColumn(); newColumn.setName("number"); newColumn.setTitle("number"); addToColumns(newColumn); return newColumn; } public FIBIconColumn createIconColumn() { FIBIconColumn newColumn = new FIBIconColumn(); newColumn.setName("icon"); newColumn.setTitle("icon"); addToColumns(newColumn); return newColumn; } public FIBCustomColumn createCustomColumn() { FIBCustomColumn newColumn = new FIBCustomColumn(); newColumn.setName("custom"); newColumn.setTitle("custom"); addToColumns(newColumn); return newColumn; } public FIBButtonColumn createButtonColumn() { FIBButtonColumn newColumn = new FIBButtonColumn(); newColumn.setName("button"); newColumn.setTitle("button"); addToColumns(newColumn); return newColumn; } public FIBTableColumn deleteColumn(FIBTableColumn columnToDelete) { logger.info("Called deleteColumn() with " + columnToDelete); removeFromColumns(columnToDelete); return columnToDelete; } public void moveToTop(FIBTableColumn c) { if (c == null) { return; } columns.remove(c); columns.add(0, c); setChanged(); notifyObservers(new FIBAddingNotification<FIBTableColumn>(Parameters.columns, c)); } public void moveUp(FIBTableColumn c) { if (c == null) { return; } int index = columns.indexOf(c); columns.remove(c); columns.add(index - 1, c); setChanged(); notifyObservers(new FIBAddingNotification<FIBTableColumn>(Parameters.columns, c)); } public void moveDown(FIBTableColumn c) { if (c == null) { return; } int index = columns.indexOf(c); columns.remove(c); columns.add(index + 1, c); setChanged(); notifyObservers(new FIBAddingNotification<FIBTableColumn>(Parameters.columns, c)); } public void moveToBottom(FIBTableColumn c) { if (c == null) { return; } columns.remove(c); columns.add(c); setChanged(); notifyObservers(new FIBAddingNotification<FIBTableColumn>(Parameters.columns, c)); } public SelectionMode getSelectionMode() { return selectionMode; } public void setSelectionMode(SelectionMode selectionMode) { FIBAttributeNotification<SelectionMode> notification = requireChange(Parameters.selectionMode, selectionMode); if (notification != null) { this.selectionMode = selectionMode; hasChanged(notification); } } public Color getTextSelectionColor() { return textSelectionColor; } public void setTextSelectionColor(Color textSelectionColor) { FIBAttributeNotification<Color> notification = requireChange(Parameters.textSelectionColor, textSelectionColor); if (notification != null) { this.textSelectionColor = textSelectionColor; hasChanged(notification); } } public Color getTextNonSelectionColor() { return textNonSelectionColor; } public void setTextNonSelectionColor(Color textNonSelectionColor) { FIBAttributeNotification<Color> notification = requireChange(Parameters.textNonSelectionColor, textNonSelectionColor); if (notification != null) { this.textNonSelectionColor = textNonSelectionColor; hasChanged(notification); } } public Color getBackgroundSelectionColor() { return backgroundSelectionColor; } public void setBackgroundSelectionColor(Color backgroundSelectionColor) { FIBAttributeNotification<Color> notification = requireChange(Parameters.backgroundSelectionColor, backgroundSelectionColor); if (notification != null) { this.backgroundSelectionColor = backgroundSelectionColor; hasChanged(notification); } } public Color getBackgroundSecondarySelectionColor() { return backgroundSecondarySelectionColor; } public void setBackgroundSecondarySelectionColor(Color backgroundSecondarySelectionColor) { FIBAttributeNotification<Color> notification = requireChange(Parameters.backgroundSecondarySelectionColor, backgroundSecondarySelectionColor); if (notification != null) { this.backgroundSecondarySelectionColor = backgroundSecondarySelectionColor; hasChanged(notification); } } public Color getBackgroundNonSelectionColor() { return backgroundNonSelectionColor; } public void setBackgroundNonSelectionColor(Color backgroundNonSelectionColor) { FIBAttributeNotification<Color> notification = requireChange(Parameters.backgroundNonSelectionColor, backgroundNonSelectionColor); if (notification != null) { this.backgroundNonSelectionColor = backgroundNonSelectionColor; hasChanged(notification); } } }