/*
* (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.Type;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import java.util.logging.Logger;
import javax.swing.tree.TreeSelectionModel;
import org.openflexo.antar.binding.BindingDefinition;
import org.openflexo.antar.binding.BindingDefinition.BindingDefinitionType;
import org.openflexo.antar.binding.ParameterizedTypeImpl;
import org.openflexo.antar.binding.TypeUtils;
import org.openflexo.fib.controller.FIBBrowserDynamicModel;
public class FIBBrowser extends FIBWidget {
private static final Logger logger = Logger.getLogger(FIBBrowser.class.getPackage().getName());
private BindingDefinition SELECTED;
private BindingDefinition ROOT;
public BindingDefinition getSelectedBindingDefinition() {
if (SELECTED == null) {
SELECTED = new BindingDefinition("selected", Object.class, BindingDefinitionType.GET_SET, false);
}
return SELECTED;
}
public BindingDefinition getRootBindingDefinition() {
if (ROOT == null) {
ROOT = new BindingDefinition("root", getIteratorClass(), BindingDefinitionType.GET, false);
}
return ROOT;
}
public static enum Parameters implements FIBModelAttribute {
root,
iteratorClass,
visibleRowCount,
rowHeight,
boundToSelectionManager,
selectionMode,
selected,
elements,
showFooter,
rootVisible,
showRootsHandle,
textSelectionColor,
textNonSelectionColor,
backgroundSelectionColor,
backgroundSecondarySelectionColor,
backgroundNonSelectionColor,
borderSelectionColor
}
public enum SelectionMode {
SingleTreeSelection {
@Override
public int getMode() {
return TreeSelectionModel.SINGLE_TREE_SELECTION;
}
},
ContiguousTreeSelection {
@Override
public int getMode() {
return TreeSelectionModel.CONTIGUOUS_TREE_SELECTION;
}
},
DiscontiguousTreeSelection {
@Override
public int getMode() {
return TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;
}
};
public abstract int getMode();
}
private DataBinding root;
private DataBinding selected;
private Integer visibleRowCount;
private Integer rowHeight;
private boolean boundToSelectionManager = false;
private SelectionMode selectionMode = SelectionMode.DiscontiguousTreeSelection;
private boolean showFooter = true;
private boolean rootVisible = true;
private boolean showRootsHandle = true;
private Color textSelectionColor;
private Color textNonSelectionColor;
private Color backgroundSelectionColor;
private Color backgroundSecondarySelectionColor;
private Color backgroundNonSelectionColor;
private Color borderSelectionColor;
private Class iteratorClass;
private Vector<FIBBrowserElement> elements;
private Hashtable<Class, FIBBrowserElement> elementsForClasses;
public FIBBrowser() {
elements = new Vector<FIBBrowserElement>();
elementsForClasses = new Hashtable<Class, FIBBrowserElement>();
}
@Override
protected String getBaseName() {
return "Browser";
}
public DataBinding getRoot() {
if (root == null) {
root = new DataBinding(this, Parameters.root, getRootBindingDefinition());
}
return root;
}
public void setRoot(DataBinding root) {
root.setOwner(this);
root.setBindingAttribute(Parameters.root);
root.setBindingDefinition(getRootBindingDefinition());
this.root = root;
}
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());
super.finalizeDeserialization();
// Give a chance to the iterator to be typed
for (FIBBrowserElement element : getElements()) {
element.finalizeBrowserDeserialization();
}
if (selected != null) {
selected.finalizeDeserialization();
}
}
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;
hasChanged(notification);
}
}
@Override
public Type getDefaultDataClass() {
return Object.class;
}
@Override
public Type getDynamicAccessType() {
Type[] args = new Type[2];
args[0] = getIteratorClass();
args[1] = getIteratorClass();
return new ParameterizedTypeImpl(FIBBrowserDynamicModel.class, args);
}
@Override
public Boolean getManageDynamicModel() {
return true;
}
/*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;
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 getBoundToSelectionManager() {
return boundToSelectionManager;
}
public void setBoundToSelectionManager(boolean boundToSelectionManager) {
FIBAttributeNotification<Boolean> notification = requireChange(Parameters.boundToSelectionManager, boundToSelectionManager);
if (notification != null) {
this.boundToSelectionManager = boundToSelectionManager;
hasChanged(notification);
}
}
public Vector<FIBBrowserElement> getElements() {
return elements;
}
public void setElements(Vector<FIBBrowserElement> elements) {
this.elements = elements;
updateElementsForClasses();
}
public void addToElements(FIBBrowserElement anElement) {
anElement.setBrowser(this);
elements.add(anElement);
updateElementsForClasses();
setChanged();
notifyObservers(new FIBAddingNotification<FIBBrowserElement>(Parameters.elements, anElement));
}
public void removeFromElements(FIBBrowserElement anElement) {
anElement.setBrowser(null);
elements.remove(anElement);
updateElementsForClasses();
setChanged();
notifyObservers(new FIBRemovingNotification<FIBBrowserElement>(Parameters.elements, anElement));
}
public FIBBrowserElement createElement() {
logger.info("Called createElement()");
FIBBrowserElement newElement = new FIBBrowserElement();
newElement.setName("element" + (elements.size() > 0 ? elements.size() : ""));
addToElements(newElement);
return newElement;
}
public FIBBrowserElement deleteElement(FIBBrowserElement elementToDelete) {
logger.info("Called elementToDelete() with " + elementToDelete);
removeFromElements(elementToDelete);
return elementToDelete;
}
public void moveToTop(FIBBrowserElement e) {
if (e == null) {
return;
}
elements.remove(e);
elements.insertElementAt(e, 0);
setChanged();
notifyObservers(new FIBAddingNotification<FIBBrowserElement>(Parameters.elements, e));
}
public void moveUp(FIBBrowserElement e) {
if (e == null) {
return;
}
int index = elements.indexOf(e);
elements.remove(e);
elements.insertElementAt(e, index - 1);
setChanged();
notifyObservers(new FIBAddingNotification<FIBBrowserElement>(Parameters.elements, e));
}
public void moveDown(FIBBrowserElement e) {
if (e == null) {
return;
}
int index = elements.indexOf(e);
elements.remove(e);
elements.insertElementAt(e, index + 1);
setChanged();
notifyObservers(new FIBAddingNotification<FIBBrowserElement>(Parameters.elements, e));
}
public void moveToBottom(FIBBrowserElement e) {
if (e == null) {
return;
}
elements.remove(e);
elements.add(e);
setChanged();
notifyObservers(new FIBAddingNotification<FIBBrowserElement>(Parameters.elements, e));
}
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);
}
}
protected void updateElementsForClasses() {
elementsForClasses.clear();
for (FIBBrowserElement e : elements) {
if (e.getDataClass() instanceof Class) {
elementsForClasses.put(e.getDataClass(), e);
}
}
}
public FIBBrowserElement elementForClass(Class<?> aClass) {
FIBBrowserElement returned = elementsForClasses.get(aClass);
if (returned != null) {
return returned;
} else {
Class<?> superclass = aClass.getSuperclass();
if (superclass != null) {
returned = elementsForClasses.get(aClass);
if (returned != null) {
return returned;
} else {
for (Class<?> superInterface : aClass.getInterfaces()) {
returned = elementsForClasses.get(superInterface);
if (returned != null) {
return returned;
}
}
returned = elementForClass(superclass);
if (returned != null) {
elementsForClasses.put(aClass, returned);
return returned;
} else {
for (Class<?> superInterface : aClass.getInterfaces()) {
returned = elementForClass(superInterface);
if (returned != null) {
elementsForClasses.put(aClass, returned);
return returned;
}
}
}
}
}
}
List<Class<?>> matchingClasses = new ArrayList<Class<?>>();
for (Class<?> cl : elementsForClasses.keySet()) {
if (cl.isAssignableFrom(aClass)) {
matchingClasses.add(cl);
}
}
if (matchingClasses.size() > 0) {
return elementsForClasses.get(TypeUtils.getMostSpecializedClass(matchingClasses));
}
return null;
}
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 getRootVisible() {
return rootVisible;
}
public void setRootVisible(boolean rootVisible) {
FIBAttributeNotification<Boolean> notification = requireChange(Parameters.rootVisible, rootVisible);
if (notification != null) {
this.rootVisible = rootVisible;
hasChanged(notification);
}
}
public boolean getShowRootsHandle() {
return showRootsHandle;
}
public void setShowRootsHandle(boolean showRootsHandle) {
FIBAttributeNotification<Boolean> notification = requireChange(Parameters.showRootsHandle, showRootsHandle);
if (notification != null) {
this.showRootsHandle = showRootsHandle;
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);
}
}
public Color getBorderSelectionColor() {
return borderSelectionColor;
}
public void setBorderSelectionColor(Color borderSelectionColor) {
FIBAttributeNotification<Color> notification = requireChange(Parameters.borderSelectionColor, borderSelectionColor);
if (notification != null) {
this.borderSelectionColor = borderSelectionColor;
hasChanged(notification);
}
}
@Override
public void notifiedBindingModelRecreated() {
super.notifiedBindingModelRecreated();
for (FIBBrowserElement e : getElements()) {
e.notifiedBindingModelRecreated();
}
}
}