2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
7 package gov
.nasa
.worldwind
.examples
;
9 import gov
.nasa
.worldwind
.WorldWindow
;
10 import gov
.nasa
.worldwind
.avlist
.*;
11 import gov
.nasa
.worldwind
.layers
.*;
12 import gov
.nasa
.worldwind
.wms
.*;
16 import javax
.swing
.border
.*;
17 import javax
.xml
.parsers
.*;
19 import java
.awt
.event
.*;
24 * @version $Id: WMSLayersPanel.java 2471 2007-07-31 21:50:57Z tgaskins $
26 public class WMSLayersPanel
extends JPanel
28 private final WorldWindow wwd
;
29 private final URI serverURI
;
30 private final Dimension size
;
31 private final LayerList layerList
= new LayerList();
32 private final Thread loadingThread
;
33 private Capabilities caps
;
35 public WMSLayersPanel(WorldWindow wwd
, String server
, Dimension size
) throws URISyntaxException
37 super(new BorderLayout());
39 // See if the server name is a valid URI. Throw an exception if not.
40 this.serverURI
= new URI(server
.trim()); // throws an exception if server name is not a valid uri.
44 this.setPreferredSize(this.size
);
46 this.makeProgressPanel();
48 // Thread off a retrieval of the server's capabilities document and update of this panel.
49 this.loadingThread
= new Thread(new Runnable()
56 this.loadingThread
.start();
63 // Retrieve the server's capabilities document and parse it into a DOM.
65 DocumentBuilderFactory docBuilderFactory
= DocumentBuilderFactory
.newInstance();
66 docBuilderFactory
.setNamespaceAware(true);
67 DocumentBuilder docBuilder
= docBuilderFactory
.newDocumentBuilder();
70 // Request the capabilities document from the server.
71 CapabilitiesRequest req
= new CapabilitiesRequest(serverURI
);
72 doc
= docBuilder
.parse(req
.toString());
74 // Parse the DOM as a capabilities document.
75 this.caps
= Capabilities
.parse(doc
);
83 // Gather up all the named layers and make a world wind layer for each.
84 final Element
[] namedLayers
= WMSLayersPanel
.this.caps
.getNamedLayers();
85 if (namedLayers
== null)
90 for (Element layerCaps
: namedLayers
)
92 Element
[] styles
= caps
.getLayerStyles(layerCaps
);
95 Layer layer
= createLayer(WMSLayersPanel
.this.caps
, layerCaps
, null);
96 WMSLayersPanel
.this.layerList
.add(layer
);
100 for (Element style
: styles
)
102 Layer layer
= createLayer(WMSLayersPanel
.this.caps
, layerCaps
, style
);
103 WMSLayersPanel
.this.layerList
.add(layer
);
114 // Fill the panel with the layer titles.
115 EventQueue
.invokeLater(new Runnable()
119 WMSLayersPanel
.this.removeAll();
120 makeLayersPanel(layerList
);
125 public LayerList
getLayerList()
127 return this.layerList
;
130 public Capabilities
getCaps()
135 private void makeProgressPanel()
137 // Create the panel holding the progress bar during loading.
139 JPanel outerPanel
= new JPanel(new BorderLayout());
140 outerPanel
.setBorder(BorderFactory
.createEmptyBorder(5, 5, 5, 5));
141 outerPanel
.setPreferredSize(this.size
);
143 JPanel innerPanel
= new JPanel(new BorderLayout());
144 innerPanel
.setBorder(BorderFactory
.createEmptyBorder(5, 5, 5, 5));
145 JProgressBar progressBar
= new JProgressBar();
146 progressBar
.setIndeterminate(true);
147 innerPanel
.add(progressBar
, BorderLayout
.CENTER
);
149 JButton cancelButton
= new JButton("Cancel");
150 innerPanel
.add(cancelButton
, BorderLayout
.EAST
);
151 cancelButton
.addActionListener(new AbstractAction()
153 public void actionPerformed(ActionEvent actionEvent
)
155 if (loadingThread
.isAlive())
156 loadingThread
.interrupt();
158 Container c
= WMSLayersPanel
.this.getParent();
159 c
.remove(WMSLayersPanel
.this);
163 outerPanel
.add(innerPanel
, BorderLayout
.NORTH
);
164 this.add(outerPanel
, BorderLayout
.CENTER
);
168 private void makeLayersPanel(LayerList layerList
)
170 // Create the panel holding the layer names.
171 JPanel layersPanel
= new JPanel(new GridLayout(0, 1, 0, 15));
172 layersPanel
.setBorder(BorderFactory
.createEmptyBorder(5, 5, 5, 5));
174 // Add the server's layers to the panel.
175 for (Layer layer
: layerList
)
177 addLayerToPanel(layersPanel
, WMSLayersPanel
.this.wwd
, layer
);
180 // Put the name panel in a scroll bar.
181 JScrollPane scrollPane
= new JScrollPane(layersPanel
);
182 scrollPane
.setBorder(BorderFactory
.createEmptyBorder(0, 0, 0, 0));
183 scrollPane
.setPreferredSize(size
);
185 // Add the scroll bar and name panel to a titled panel that will resize with the main window.
186 JPanel westPanel
= new JPanel(new GridLayout(0, 1, 0, 10));
188 new CompoundBorder(BorderFactory
.createEmptyBorder(9, 9, 9, 9), new TitledBorder("Layers")));
189 westPanel
.add(scrollPane
);
190 this.add(westPanel
, BorderLayout
.CENTER
);
195 public String
getServerDisplayString()
197 // Find the best available name for the server.
201 // Capabilities have not yet been retrieved, so use the host name of the server's URI.
202 return this.serverURI
.getHost();
205 if (this.caps
.getTitle() != null && this.caps
.getTitle().length() > 0)
206 return this.caps
.getTitle();
208 if (this.caps
.getName() != null && this.caps
.getName().length() > 0)
209 return this.caps
.getName();
214 private Layer
createLayer(Capabilities caps
, Element layerCaps
, Element style
)
216 // Create the layer specified by the layer's capabilities entry and the selected style.
218 AVListImpl params
= new AVListImpl();
219 params
.setValue(AVKey
.LAYER_NAMES
, caps
.getLayerName(layerCaps
));
221 params
.setValue(AVKey
.STYLE_NAMES
, caps
.getStyleName(style
));
223 Layer layer
= WMSLayerFactory
.newLayer(caps
, params
);
224 layer
.setEnabled(false);
226 // Some wms servers are slow, so increase the timeouts and limits used by world wind's retrievers.
227 layer
.setValue(AVKey
.URL_CONNECT_TIMEOUT
, 30000);
228 layer
.setValue(AVKey
.URL_READ_TIMEOUT
, 30000);
229 layer
.setValue(AVKey
.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT
, 60000);
234 private void addLayerToPanel(JPanel layersPanel
, WorldWindow wwd
, Layer layer
)
236 // Give a layer a button and label and add it to the layer names panel.
238 LayerAction action
= new LayerAction(layer
, wwd
);
239 JCheckBox jcb
= new JCheckBox(action
);
240 jcb
.setSelected(layer
.isEnabled());
241 layersPanel
.add(jcb
);
244 private class LayerAction
extends AbstractAction
246 private WorldWindow wwd
;
249 public LayerAction(Layer layer
, WorldWindow wwd
)
251 // Capture info we'll need later to control the layer.
252 super(layer
.getName());
256 // Add the layer to the world window model's layer list if the layer is enabled.
257 if (layer
.isEnabled())
259 ApplicationTemplate
.insertBeforePlacenames(this.wwd
, this.layer
);
263 public void actionPerformed(ActionEvent actionEvent
)
265 // If the layer is selected, add it to the world window's current model, else remove it from the model.
266 if (((JCheckBox
) actionEvent
.getSource()).isSelected())
268 this.layer
.setEnabled(true);
269 ApplicationTemplate
.insertBeforePlacenames(this.wwd
, this.layer
);
270 WMSLayersPanel
.this.firePropertyChange("LayersPanelUpdated", null, layer
);
274 this.layer
.setEnabled(false);
275 this.wwd
.getModel().getLayers().remove(layer
);
276 WMSLayersPanel
.this.firePropertyChange("LayersPanelUpdated", layer
, null);
279 // Tell the world window to update.