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
.*;
10 import gov
.nasa
.worldwind
.layers
.*;
11 import gov
.nasa
.worldwind
.wms
.*;
15 import javax
.swing
.border
.*;
16 import javax
.xml
.parsers
.*;
18 import java
.awt
.event
.*;
23 * @version $Id: WMSLayersPanel.java 2131 2007-06-22 22:45:35Z jason $
25 public class WMSLayersPanel
extends JPanel
27 private final WorldWindow wwd
;
28 private final URI serverURI
;
29 private final Dimension size
;
30 private final LayerList layerList
= new LayerList();
31 private final Thread loadingThread
;
32 private Capabilities caps
;
34 public WMSLayersPanel(WorldWindow wwd
, String server
, Dimension size
) throws URISyntaxException
36 super(new BorderLayout());
38 // See if the server name is a valid URI. Throw an exception if not.
39 this.serverURI
= new URI(server
); // throws an exception if server name is not a valid uri.
43 this.setPreferredSize(this.size
);
45 this.makeProgressPanel();
47 // Thread off a retrieval of the server's capabilities document and update of this panel.
48 this.loadingThread
= new Thread(new Runnable()
55 this.loadingThread
.start();
62 // Retrieve the server's capabilities document and parse it into a DOM.
64 DocumentBuilderFactory docBuilderFactory
= DocumentBuilderFactory
.newInstance();
65 docBuilderFactory
.setNamespaceAware(true);
66 DocumentBuilder docBuilder
= docBuilderFactory
.newDocumentBuilder();
69 // Request the capabilities document from the server.
70 CapabilitiesRequest req
= new CapabilitiesRequest(serverURI
);
71 doc
= docBuilder
.parse(req
.toString());
73 // Parse the DOM as a capabilities document.
74 this.caps
= Capabilities
.parse(doc
);
82 // Gather up all the named layers and make a world wind layer for each.
83 final Element
[] namedLayers
= WMSLayersPanel
.this.caps
.getNamedLayers();
84 if (namedLayers
== null)
89 for (Element layerCaps
: namedLayers
)
91 Element
[] styles
= caps
.getLayerStyles(layerCaps
);
94 Layer layer
= createLayer(WMSLayersPanel
.this.caps
, layerCaps
, null);
95 WMSLayersPanel
.this.layerList
.add(layer
);
99 for (Element style
: styles
)
101 Layer layer
= createLayer(WMSLayersPanel
.this.caps
, layerCaps
, style
);
102 WMSLayersPanel
.this.layerList
.add(layer
);
113 // Fill the panel with the layer titles.
114 EventQueue
.invokeLater(new Runnable()
118 WMSLayersPanel
.this.removeAll();
119 makeLayersPanel(layerList
);
124 public LayerList
getLayerList()
126 return this.layerList
;
129 public Capabilities
getCaps()
134 private void makeProgressPanel()
136 // Create the panel holding the progress bar during loading.
138 JPanel outerPanel
= new JPanel(new BorderLayout());
139 outerPanel
.setBorder(BorderFactory
.createEmptyBorder(5, 5, 5, 5));
140 outerPanel
.setPreferredSize(this.size
);
142 JPanel innerPanel
= new JPanel(new BorderLayout());
143 innerPanel
.setBorder(BorderFactory
.createEmptyBorder(5, 5, 5, 5));
144 JProgressBar progressBar
= new JProgressBar();
145 progressBar
.setIndeterminate(true);
146 innerPanel
.add(progressBar
, BorderLayout
.CENTER
);
148 JButton cancelButton
= new JButton("Cancel");
149 innerPanel
.add(cancelButton
, BorderLayout
.EAST
);
150 cancelButton
.addActionListener(new AbstractAction()
152 public void actionPerformed(ActionEvent actionEvent
)
154 if (loadingThread
.isAlive())
155 loadingThread
.interrupt();
157 Container c
= WMSLayersPanel
.this.getParent();
158 c
.remove(WMSLayersPanel
.this);
162 outerPanel
.add(innerPanel
, BorderLayout
.NORTH
);
163 this.add(outerPanel
, BorderLayout
.CENTER
);
167 private void makeLayersPanel(LayerList layerList
)
169 // Create the panel holding the layer names.
170 JPanel layersPanel
= new JPanel(new GridLayout(0, 1, 0, 15));
171 layersPanel
.setBorder(BorderFactory
.createEmptyBorder(5, 5, 5, 5));
173 // Add the server's layers to the panel.
174 for (Layer layer
: layerList
)
176 addLayerToPanel(layersPanel
, WMSLayersPanel
.this.wwd
, layer
);
179 // Put the name panel in a scroll bar.
180 JScrollPane scrollPane
= new JScrollPane(layersPanel
);
181 scrollPane
.setBorder(BorderFactory
.createEmptyBorder(0, 0, 0, 0));
182 scrollPane
.setPreferredSize(size
);
184 // Add the scroll bar and name panel to a titled panel that will resize with the main window.
185 JPanel westPanel
= new JPanel(new GridLayout(0, 1, 0, 10));
187 new CompoundBorder(BorderFactory
.createEmptyBorder(9, 9, 9, 9), new TitledBorder("Layers")));
188 westPanel
.add(scrollPane
);
189 this.add(westPanel
, BorderLayout
.CENTER
);
194 public String
getServerDisplayString()
196 // Find the best available name for the server.
200 // Capabilities have not yet been retrieved, so use the host name of the server's URI.
201 return this.serverURI
.getHost();
204 if (this.caps
.getTitle() != null && this.caps
.getTitle().length() > 0)
205 return this.caps
.getTitle();
207 if (this.caps
.getName() != null && this.caps
.getName().length() > 0)
208 return this.caps
.getName();
213 private Layer
createLayer(Capabilities caps
, Element layerCaps
, Element style
)
215 // Create the layer specified by the layer's capabilities entry and the selected style.
217 AVListImpl params
= new AVListImpl();
218 params
.setValue(AVKey
.LAYER_NAMES
, caps
.getLayerName(layerCaps
));
220 params
.setValue(AVKey
.STYLE_NAMES
, caps
.getStyleName(style
));
222 Layer layer
= WMSLayerFactory
.newLayer(caps
, params
);
223 layer
.setEnabled(false);
225 // Some wms servers are slow, so increase the timeouts and limits used by world wind's retrievers.
226 layer
.setValue(AVKey
.URL_CONNECT_TIMEOUT
, 30000);
227 layer
.setValue(AVKey
.URL_READ_TIMEOUT
, 30000);
228 layer
.setValue(AVKey
.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT
, 60000);
233 private void addLayerToPanel(JPanel layersPanel
, WorldWindow wwd
, Layer layer
)
235 // Give a layer a button and label and add it to the layer names panel.
237 LayerAction action
= new LayerAction(layer
, wwd
);
238 JCheckBox jcb
= new JCheckBox(action
);
239 jcb
.setSelected(layer
.isEnabled());
240 layersPanel
.add(jcb
);
243 private class LayerAction
extends AbstractAction
245 private WorldWindow wwd
;
248 public LayerAction(Layer layer
, WorldWindow wwd
)
250 // Capture info we'll need later to control the layer.
251 super(layer
.getName());
255 // Add the layer to the world window model's layer list if the layer is enabled.
256 if (layer
.isEnabled())
258 ApplicationTemplate
.insertBeforePlacenames(this.wwd
, this.layer
);
262 public void actionPerformed(ActionEvent actionEvent
)
264 // If the layer is selected, add it to the world window's current model, else remove it from the model.
265 if (((JCheckBox
) actionEvent
.getSource()).isSelected())
267 this.layer
.setEnabled(true);
268 ApplicationTemplate
.insertBeforePlacenames(this.wwd
, this.layer
);
269 WMSLayersPanel
.this.firePropertyChange("LayersPanelUpdated", null, layer
);
273 this.layer
.setEnabled(false);
274 this.wwd
.getModel().getLayers().remove(layer
);
275 WMSLayersPanel
.this.firePropertyChange("LayersPanelUpdated", layer
, null);
278 // Tell the world window to update.