/* * (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.view; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JComponent; import javax.swing.SwingUtilities; import org.openflexo.antar.binding.TypeUtils; import org.openflexo.fib.controller.FIBController; import org.openflexo.fib.model.FIBComponent; import org.openflexo.fib.model.FIBContainer; public abstract class FIBContainerView<M extends FIBContainer, J extends JComponent> extends FIBView<M, J> { private static final Logger logger = Logger.getLogger(FIBContainerView.class.getPackage().getName()); private Vector<JComponent> subComponents; private Hashtable<JComponent, Object> constraints; public FIBContainerView(M model, FIBController controller) { super(model, controller); subComponents = new Vector<JComponent>(); constraints = new Hashtable<JComponent, Object>(); createJComponent(); buildSubComponents(); } @Override public void delete() { if (isDeleted()) { return; } subComponents.clear(); constraints.clear(); subComponents = null; constraints = null; super.delete(); } protected synchronized void buildSubComponents() { subViews.clear(); subComponents.clear(); constraints.clear(); retrieveContainedJComponentsAndConstraints(); for (JComponent j : subComponents) { addJComponent(j); } updatePreferredSize(); updateFont(); getJComponent().revalidate(); getJComponent().repaint(); } protected abstract J createJComponent(); protected abstract void retrieveContainedJComponentsAndConstraints(); protected void addJComponent(JComponent c) { // logger.info("addJComponent constraints=" + c); Object constraint = constraints.get(c); logger.fine(getComponent() + ": addJComponent " + c + " constraint=" + constraint); if (constraint == null) { getJComponent().add(c); } else { getJComponent().add(c, constraint); } } @Override public abstract J getJComponent(); @Override public J getDynamicJComponent() { return getJComponent(); } public Object getValue() { if (getDataObject() == null) { return null; } if (getComponent().getData() == null || getComponent().getData().isUnset()) { return null; } return getComponent().getData().getBindingValue(getController()); } @Override public void updateDataObject(final Object dataObject) { if (!SwingUtilities.isEventDispatchThread()) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Update data object invoked outside the EDT!!! please investigate and make sure this is no longer the case. \n\tThis is a very SERIOUS problem! Do not let this pass."); } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { updateDataObject(dataObject); } }); return; } update(new Vector<FIBComponent>()); if (isComponentVisible()) { for (FIBView v : new ArrayList<FIBView>(subViews)) { v.updateDataObject(dataObject); } if (getDynamicModel() != null) { logger.fine("Container: " + getComponent() + " value data for " + getDynamicModel() + " is " + getValue()); getDynamicModel().setData(getValue()); notifyDynamicModelChanged(); } } } @Override protected boolean checkValidDataPath() { if (getParentView() != null && !getParentView().checkValidDataPath()) { return false; } if (getComponent().getDataType() != null) { Object value = getValue(); if (value != null && !TypeUtils.isTypeAssignableFrom(getComponent().getDataType(), value.getClass(), true)) { // logger.fine("INVALID data path for component "+getComponent()); // logger.fine("Value is "+getValue().getClass()+" while expected type is "+getComponent().getDataType()); return false; } } return true; } @Override public void updateLanguage() { for (FIBView v : subViews) { // if (!"True".equals(v.getComponent().getParameter(FIBContainer.INHERITED))) v.updateLanguage(); } } /** * This method is called to update view representing a FIBComponent.<br> * Callers are all the components that have been updated during current update loop. If the callers contains the component itself, does * nothing and return. * * @param callers * all the components that have been previously updated during current update loop * @return a flag indicating if component has been updated */ @Override public boolean update(List<FIBComponent> callers) { return super.update(callers); } protected void registerViewForComponent(FIBView view, FIBComponent component) { subViews.add(view); } protected void registerComponentWithConstraints(JComponent component, Object constraint) { registerComponentWithConstraints(component, constraint, -1); } protected void registerComponentWithConstraints(JComponent component, Object constraint, int index) { logger.fine("Register component: " + component + " constraint=" + constraint); if (index < 0 || index > subComponents.size()) { index = subComponents.size(); } subComponents.add(index, component); if (constraint != null) { constraints.put(component, constraint); } } protected void registerComponentWithConstraints(JComponent component, int index) { registerComponentWithConstraints(component, null, index); } protected void registerComponentWithConstraints(JComponent component) { registerComponentWithConstraints(component, null, -1); } /*protected void registerComponentWithConstraints(JComponent component, int index) { logger.fine("Register component: "+component+" index="+index); subComponents.insertElementAt(component,index); } protected void registerComponentWithConstraints(JComponent component, Object constraint, int index) { logger.fine("Register component: "+component+" index="+index); subComponents.insertElementAt(component,index); if (constraint != null) constraints.put(component,constraint); }*/ protected Vector<JComponent> getSubComponents() { return subComponents; } protected Hashtable<JComponent, Object> getConstraints() { return constraints; } @Override public synchronized void updateFont() { if (getFont() != null) { getJComponent().setFont(getFont()); } for (FIBView v : subViews) { v.updateFont(); } getJComponent().revalidate(); getJComponent().repaint(); } public abstract void updateLayout(); }