001/* 002 * $Id: McvComponentHolder.java,v 1.10 2011/03/24 16:06:34 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2011 007 * Space Science and Engineering Center (SSEC) 008 * University of Wisconsin - Madison 009 * 1225 W. Dayton Street, Madison, WI 53706, USA 010 * https://www.ssec.wisc.edu/mcidas 011 * 012 * All Rights Reserved 013 * 014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 015 * some McIDAS-V source code is based on IDV and VisAD source code. 016 * 017 * McIDAS-V is free software; you can redistribute it and/or modify 018 * it under the terms of the GNU Lesser Public License as published by 019 * the Free Software Foundation; either version 3 of the License, or 020 * (at your option) any later version. 021 * 022 * McIDAS-V is distributed in the hope that it will be useful, 023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 025 * GNU Lesser Public License for more details. 026 * 027 * You should have received a copy of the GNU Lesser Public License 028 * along with this program. If not, see http://www.gnu.org/licenses. 029 */ 030 031package edu.wisc.ssec.mcidasv.ui; 032 033import java.util.List; 034 035import javax.swing.JComponent; 036 037import org.w3c.dom.Document; 038import org.w3c.dom.Element; 039 040import ucar.unidata.idv.IntegratedDataViewer; 041import ucar.unidata.idv.ui.IdvComponentHolder; 042import ucar.unidata.idv.ui.IdvUIManager; 043import ucar.unidata.idv.ui.IdvXmlUi; 044import ucar.unidata.idv.ViewManager; 045import ucar.unidata.util.WrapperException; 046import ucar.unidata.xml.XmlUtil; 047 048/** 049 * <p> 050 * McIDAS-V needs its own ComponentHolder merely to associate ViewManagers with 051 * their parent ComponentHolders. This association is later used in 052 * McIDASVViewPanel to create a "hierarchical name" for each ViewManager. 053 * </p> 054 * 055 * <p> 056 * Instead of having something like "Panel 1" appearing in the layer controls, 057 * we now have "ComponentHolder Name>Panel 1". Note: ComponentHolder names 058 * always double as tab names! McV also intercepts ComponentHolder renaming and 059 * updates the layer controls instantly. 060 * </p> 061 */ 062public class McvComponentHolder extends IdvComponentHolder { 063 064 /** IDV friendly description of a dynamic XML skin. */ 065 public static final String CATEGORY_DESCRIPTION = "UI Skin"; 066 067 /** Used to distinguish a dynamic skin from other things. */ 068 public static final String TYPE_DYNAMIC_SKIN = "dynamicskin"; 069 070// private static Logger logger = LoggerFactory.getLogger(McvComponentHolder.class); 071 072// private Map<String, ViewManager> dynamicViewManagers = new HashMap<String, ViewManager>(); 073 074 /** Kept around to avoid annoying casting. */ 075 private UIManager uiManager; 076 077 private JComponent cached = null; 078 079 /** 080 * Default constructor for serialization. 081 */ 082 public McvComponentHolder() { 083 } 084 085 /** 086 * Fairly typical constructor. 087 * 088 * @param idv Reference to the main IDV object. 089 * @param obj object being held in this component holder. 090 */ 091 public McvComponentHolder(IntegratedDataViewer idv, Object obj) { 092 super(idv, obj); 093 uiManager = (UIManager)idv.getIdvUIManager(); 094 } 095 096 /** 097 * Overridden so that we can (one day) do the required extra work to write 098 * out the XML for this skin. 099 * 100 * @param doc Parent document we'll use for XML generation. 101 * 102 * @return XML representation of what is being held. 103 */ 104 @Override public Element createXmlNode(Document doc) { 105 if (!getType().equals(TYPE_DYNAMIC_SKIN)) { 106 return super.createXmlNode(doc); 107 } 108 109 // keep in mind that the IDV expects that we're holding a path 110 // to a skin... I don't think that this will work how you want it... 111 // TODO: investigate this! 112 Element node = doc.createElement(IdvUIManager.COMP_COMPONENT_SKIN); 113 node.setAttribute("url", getObject().toString()); 114 115 /* 116 * try { System.err.println(XmlUtil.toString((Element)getObject())); } 117 * catch (Exception e) { e.printStackTrace(); } 118 */ 119 120 return node; 121 } 122 123 /** 124 * Overridden so that McV can do the required extra work if this holder is 125 * holding a dynamic XML skin. 126 * 127 * @return Contents of this holder as a UI component. 128 */ 129 @Override public JComponent doMakeContents() { 130 JComponent contents; 131 if (!getType().equals(TYPE_DYNAMIC_SKIN)) { 132 contents = super.doMakeContents(); 133 } else { 134 contents = makeDynamicSkin(); 135 } 136// contents.addComponentListener(new ComponentListener() { 137// @Override public void componentHidden(ComponentEvent e) { 138// logger.trace("component hidden"); 139// GuiUtils.toggleHeavyWeightComponents(contents, false); 140// } 141// @Override public void componentShown(ComponentEvent e) { 142// logger.trace("component shown"); 143// GuiUtils.toggleHeavyWeightComponents(contents, false); 144// } 145// @Override public void componentMoved(ComponentEvent e) {} 146// @Override public void componentResized(ComponentEvent e) {} 147// }); 148 return contents; 149 } 150 151 /** 152 * Lets the IDV take care of the details, but does null out the local 153 * reference to the UIManager. 154 */ 155 @Override public void doRemove() { 156 super.doRemove(); 157 uiManager = null; 158 } 159 160 /** 161 * Overridden so that McV can return a more accurate category if this holder 162 * is holding a dynamic skin. 163 * 164 * @return Category name for the type of thing we're holding. 165 */ 166 @Override public String getCategory() { 167 if (!getType().equals(TYPE_DYNAMIC_SKIN)) { 168 return super.getCategory(); 169 } 170 return CATEGORY_DESCRIPTION; 171 } 172 173 /** 174 * Overridden so that McV can return a more accurate description if this 175 * holder is holding a dynamic skin. 176 * 177 * @return The description of what is being held. 178 */ 179 @Override public String getTypeName() { 180 if (!getType().equals(TYPE_DYNAMIC_SKIN)) { 181 return super.getTypeName(); 182 } 183 return CATEGORY_DESCRIPTION; 184 } 185 186 /** 187 * <p> 188 * If the object being held in this component holder is a skin, calling this 189 * method will create a component based upon the skin. 190 * </p> 191 * 192 * <p> 193 * Overridden so that McV can tell the UIManager to associate the skin's 194 * ViewManagers with this component holder. That association is used to 195 * build the hierarchical names in the ViewPanel. 196 * </p> 197 * 198 * @return The component represented by this holder's skin. 199 */ 200 @Override protected JComponent makeSkin() { 201 JComponent comp = super.makeSkin(); 202 203 // let's hope that *getViewManagers* only gives us a list of 204 // ViewManagers 205 @SuppressWarnings("unchecked") 206 List<ViewManager> vms = getViewManagers(); 207 if (vms != null) { 208 for (int i = 0; i < vms.size(); i++) { 209 uiManager.setViewManagerHolder(vms.get(i), this); 210 uiManager.getViewPanel().viewManagerChanged(vms.get(i)); 211 } 212 } 213 return comp; 214 } 215 216 /** 217 * Mostly used to ensure that the local reference to the UI manager is valid 218 * when deserializing. 219 * 220 * @param idv Main IDV reference! 221 */ 222 @Override 223 public void setIdv(IntegratedDataViewer idv) { 224 super.setIdv(idv); 225 uiManager = (UIManager)idv.getIdvUIManager(); 226 } 227 228 /** 229 * <p> 230 * Merely sets the name of this component holder to the contents of 231 * <tt>value</tt>. 232 * </p> 233 * 234 * <p> 235 * Overridden so that McV can tell the ViewPanel to update upon a name 236 * change. 237 * </p> 238 * 239 * @param value New name of this component holder. 240 */ 241 @Override public void setName(String value) { 242 super.setName(value); 243 244 // let's hope that *getViewManagers* only gives us a list of 245 // ViewManagers 246 @SuppressWarnings("unchecked") 247 List<ViewManager> vms = getViewManagers(); 248 if (vms != null) { 249 for (int i = 0; i < vms.size(); i++) { 250 uiManager.getViewPanel().viewManagerChanged(vms.get(i)); 251 } 252 } 253 } 254 255 /** 256 * Build the UI component using the XML skin contained by this holder. 257 * 258 * @return UI Component specified by the skin contained in this holder. 259 */ 260 public JComponent makeDynamicSkin() { 261 if (cached != null) 262 return cached; 263 264 try { 265 Element root = XmlUtil.getRoot((String) getObject()); 266 267 IdvXmlUi ui = uiManager.doMakeIdvXmlUi(null, getViewManagers(), 268 root); 269 270 // look for any "embedded" ViewManagers. 271 Element startNode = XmlUtil.findElement(root, null, "embeddednode", 272 "true"); 273 if (startNode != null) { 274 ui.setStartNode(startNode); 275 } 276 277 JComponent contents = (JComponent)ui.getContents(); 278 setViewManagers(ui.getViewManagers()); 279 280 cached = contents; 281 return contents; 282 283 } catch (Exception e) { 284 throw new WrapperException(e); 285 } 286 } 287 288 /** 289 * <p> 290 * Tell this component holder's component group that the tab corresponding 291 * to this holder should become the active tab. 292 * </p> 293 */ 294 public void setAsActiveTab() { 295 McvComponentGroup parent = (McvComponentGroup)getParent(); 296 if (parent != null) { 297 parent.setActiveComponentHolder(this); 298 } 299 } 300}