/* * (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.inspector.widget; import java.awt.Component; import java.lang.reflect.Method; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.JList; import javax.swing.ListModel; import javax.swing.event.ListDataListener; import org.openflexo.inspector.AbstractController; import org.openflexo.inspector.HasIcon; import org.openflexo.inspector.InspectableObject; import org.openflexo.inspector.model.PropertyModel; import org.openflexo.kvc.ChoiceList; import org.openflexo.localization.FlexoLocalization; /** * Please comment this class * * @author sguerin * */ public abstract class MultipleValuesWidget<T> extends DenaliWidget<T> { private static final Logger logger = Logger.getLogger(MultipleValuesWidget.class.getPackage().getName()); protected static final int UNDEFINED = -1; protected static final int CHOICE_LIST = 0; protected static final int STATIC_LIST = 1; protected static final int DYNAMIC_LIST = 2; protected static final int DYNAMIC_HASH = 3; protected int valueType = UNDEFINED; private DenaliListModel listModel = null; private DenaliListCellRenderer listCellRenderer = null; protected boolean tryToShowIcon = false; /** * @param model */ protected MultipleValuesWidget(PropertyModel model, AbstractController controller) { super(model, controller); if (model.hasValueForParameter("showIcon") && model.getBooleanValueForParameter("showIcon")) { tryToShowIcon = true; } } @Override protected void setModel(InspectableObject value) { super.setModel(value); if (isChoiceList()) { valueType = CHOICE_LIST; } else if (_propertyModel.hasStaticList()) { valueType = STATIC_LIST; } else if (_propertyModel.hasDynamicList()) { valueType = DYNAMIC_LIST; } else if (_propertyModel.hasDynamicHashtable()) { valueType = DYNAMIC_HASH; } listCellRenderer = new DenaliListCellRenderer(); listModel = new DenaliListModel(); } @Override public void performUpdate() { // logger.info("Updating model for "+this); super.performUpdate(); if (isChoiceList()) { valueType = CHOICE_LIST; } else if (_propertyModel.hasStaticList()) { valueType = STATIC_LIST; } else if (_propertyModel.hasDynamicList()) { valueType = DYNAMIC_LIST; } else if (_propertyModel.hasDynamicHashtable()) { valueType = DYNAMIC_HASH; } listCellRenderer = new DenaliListCellRenderer(); listModel = new DenaliListModel(); } @Override public Class getDefaultType() { return List.class; } protected Object[] getListValues() { if (_propertyModel.hasDynamicList()) { return _propertyModel.getDynamicList(getModel()).toArray(); } else if (getType().getEnumConstants() != null) { return getType().getEnumConstants(); } else if (isChoiceList()) { if (getObjectValue() == null) { try { // Dynamic call to getType() class on method // availableValues() Method availableValuesMethod = getType().getMethod("availableValues", (Class[]) null); return ((List) availableValuesMethod.invoke(getType(), (Object[]) null)).toArray(); } catch (Exception e) { // Warns about the exception if (logger.isLoggable(Level.WARNING)) { logger.warning("Exception raised: " + e.getClass().getName() + ". See console for details."); } e.printStackTrace(); return new Object[0]; } } else { return ((ChoiceList) getObjectValue()).getAvailableValues().toArray(); } } else if (_propertyModel.hasStaticList()) { return _propertyModel.getStaticList().toArray(); } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("There is an error in some configuration file :\n the property named '" + _propertyModel.name + "' is supposed to be a list, but it doesn't hold any list definition!"); } return new Object[0]; } } protected Hashtable getHashValues() { if (_propertyModel.hasDynamicHashtable()) { return _propertyModel.getDynamicHashtable(getModel()); } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("There is an error in some configuration file :\n the property named '" + _propertyModel.name + "' is supposed to be a hashtable, but it doesn't hold any hashtable definition!"); } return new Hashtable(); } } public DenaliListCellRenderer getListCellRenderer() { if (listCellRenderer == null) { listCellRenderer = new DenaliListCellRenderer(); } return listCellRenderer; } public DenaliListModel getListModel() { if (listModel == null) { listModel = new DenaliListModel(); } return listModel; } public int getValueType() { return valueType; } protected class DenaliListCellRenderer extends DefaultListCellRenderer { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { DenaliListCellRenderer label = (DenaliListCellRenderer) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (tryToShowIcon && value instanceof HasIcon) { label.setIcon(((HasIcon) value).getIcon()); } if (value != null) { String stringRepresentation = getDisplayStringRepresentation(value); if (stringRepresentation == null || stringRepresentation.length() == 0) { stringRepresentation = "<html><i>" + FlexoLocalization.localizedForKey("empty_string") + "</i></html>"; } label.setText(stringRepresentation); } else { label.setText(FlexoLocalization.localizedForKey("no_selection")); } label.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2)); return label; } } protected class DenaliListModel implements ListModel { private Object[] _values; private Hashtable _hashValues; protected DenaliListModel() { super(); if (getModel() != null) { if (valueType == CHOICE_LIST || valueType == STATIC_LIST || valueType == DYNAMIC_LIST) { _values = getListValues(); } else if (valueType == DYNAMIC_HASH) { _hashValues = getHashValues(); } } // logger.info("values of model are: "+_values); } @Override public int getSize() { if (getModel() != null) { if (_values != null && (valueType == CHOICE_LIST || valueType == STATIC_LIST || valueType == DYNAMIC_LIST)) { return _values.length; } else if (valueType == DYNAMIC_HASH) { return _hashValues.size(); } } return 0; } @Override public Object getElementAt(int index) { if (getModel() != null) { if (valueType == CHOICE_LIST || valueType == STATIC_LIST || valueType == DYNAMIC_LIST) { return _values[index]; } else if (valueType == DYNAMIC_HASH) { Iterator it = _hashValues.values().iterator(); for (int i = 0; i < index; i++) { if (it.hasNext()) { it.next(); } } if (it.hasNext()) { return it.next(); } } if (logger.isLoggable(Level.WARNING)) { logger.warning("Inconsistent data !"); } } return null; } @Override public void addListDataListener(ListDataListener l) { // Interface } @Override public void removeListDataListener(ListDataListener l) { // Interface } public int indexOf(Object cur) { for (int i = 0; i < getSize(); i++) { if (getElementAt(i).equals(cur)) { return i; } } return -1; } } }