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