org.jgrasstools.nww.gui.LayerManagerPanel Maven / Gradle / Ivy
/*
* Copyright (C) 2013 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package org.jgrasstools.nww.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.CompoundBorder;
import javax.swing.border.TitledBorder;
import gov.nasa.worldwind.WorldWindow;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.event.RenderingEvent;
import gov.nasa.worldwind.event.RenderingListener;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.layers.LayerList;
import gov.nasa.worldwind.layers.TiledImageLayer;
/**
* Displays the available layers. Provides an interface to enable and disable them. Provides an interface to change
* their relative order. Indicates when any portion of an image layer is actually rendered.
*
* @author tag
* @version $Id: LayerManagerPanel.java 2147 2014-07-11 23:29:45Z tgaskins $
*/
public class LayerManagerPanel extends JPanel
{
protected JPanel layerNamesPanel;
protected List layerPanels = new ArrayList();
protected Font plainFont;
protected Font boldFont;
public LayerManagerPanel(final WorldWindow wwd)
{
super(new BorderLayout(10, 10));
this.layerNamesPanel = new JPanel(new GridLayout(0, 1, 0, 5));
this.layerNamesPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// Must put the layer grid in a container to prevent the scroll pane from stretching vertical spacing.
JPanel dummyPanel = new JPanel(new BorderLayout());
dummyPanel.add(this.layerNamesPanel, BorderLayout.NORTH);
// Put the layers panel in a scroll pane.
JScrollPane scrollPane = new JScrollPane(dummyPanel);
// Suppress the scroll pane's default border.
scrollPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
// Add the scroll pane to a titled panel that will resize with the main window.
JPanel titlePanel = new JPanel(new GridLayout(0, 1, 0, 10));
titlePanel.setBorder(
new CompoundBorder(BorderFactory.createEmptyBorder(9, 9, 9, 9), new TitledBorder("Layers")));
titlePanel.setToolTipText("Layers to Show");
titlePanel.add(scrollPane);
titlePanel.setPreferredSize(new Dimension(200, 500));
this.add(titlePanel, BorderLayout.CENTER);
this.fill(wwd);
this.plainFont = this.getFont().deriveFont(Font.PLAIN);
this.boldFont = this.getFont().deriveFont(Font.BOLD);
// Register a rendering listener that updates the was-rendered state of each image layer.
wwd.addRenderingListener(new RenderingListener()
{
@Override
public void stageChanged(RenderingEvent event)
{
updateLayerActivity(wwd);
}
});
// Add a property change listener that causes this layer panel to be updated whenever the layer list changes.
wwd.getModel().getLayers().addPropertyChangeListener(new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent)
{
if (propertyChangeEvent.getPropertyName().equals(AVKey.LAYERS))
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
update(wwd);
}
});
}
});
}
public void update(WorldWindow wwd)
{
// Repopulate this layer manager.
this.fill(wwd);
}
protected void fill(WorldWindow wwd)
{
// Populate this layer manager with an entry for each layer in the WorldWindow's layer list.
if (this.isUpToDate(wwd))
return;
// First remove all the existing entries.
this.layerPanels.clear();
this.layerNamesPanel.removeAll();
// Fill the layers panel with the titles of all layers in the world window's current model.
for (Layer layer : wwd.getModel().getLayers())
{
if (layer.getValue(AVKey.IGNORE) != null)
continue;
GeneralLayerPanel layerPanel = new GeneralLayerPanel(wwd, layer);
this.layerNamesPanel.add(layerPanel);
this.layerPanels.add(layerPanel);
}
this.updateLayerActivity(wwd);
}
protected boolean isUpToDate(WorldWindow wwd)
{
// Determines whether this layer manager's layer list is consistent with the specified WorldWindow's. Knowing
// this prevents redundant updates.
LayerList layerList = wwd.getModel().getLayers();
if (this.layerPanels.size() != layerList.size())
return false;
for (int i = 0; i < layerList.size(); i++)
{
if (layerList.get(i) != this.layerPanels.get(i).getLayer())
return false;
}
return true;
}
/**
* Loops through this layer panel's layer/checkbox list and updates the checkbox font to indicate whether the
* corresponding layer was just rendered. This method is called by a rendering listener -- see comment below.
*
* @param wwd the world window.
*/
protected void updateLayerActivity(WorldWindow wwd)
{
for (GeneralLayerPanel layerPanel : this.layerPanels)
{
// The frame timestamp from the layer indicates the last frame in which it rendered something. If that
// timestamp matches the current timestamp of the scene controller, then the layer rendered something
// during the most recent frame. Note that this frame timestamp protocol is only in place by default
// for TiledImageLayer and its subclasses. Applications could, however, implement it for the layers
// they design.
Long layerTimeStamp = (Long) layerPanel.getLayer().getValue(AVKey.FRAME_TIMESTAMP);
Long frameTimeStamp = (Long) wwd.getSceneController().getValue(AVKey.FRAME_TIMESTAMP);
if (layerTimeStamp != null && frameTimeStamp != null
&& layerTimeStamp.longValue() == frameTimeStamp.longValue())
{
// Set the font to bold if the layer was just rendered.
layerPanel.setLayerNameFont(this.boldFont);
}
else if (layerPanel.getLayer() instanceof TiledImageLayer)
{
// Set the font to plain if the layer was not just rendered.
layerPanel.setLayerNameFont(this.plainFont);
}
else if (layerPanel.getLayer().isEnabled())
{
// Set enabled layer types other than TiledImageLayer to bold.
layerPanel.setLayerNameFont(this.boldFont);
}
else if (!layerPanel.getLayer().isEnabled())
{
// Set disabled layer types other than TiledImageLayer to plain.
layerPanel.setLayerNameFont(this.plainFont);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy