/*
Copyright (C) 2001, 2007 United States Government as represented by
the Administrator of the National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.examples;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.layers.Earth.MGRSGraticuleLayer;
import gov.nasa.worldwind.layers.Earth.UTMGraticuleLayer;
import gov.nasa.worldwind.util.Logging;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileWriter;
/**
* @author dcollins
* @version $Id: MGRSAttributesPanel.java 5232 2008-04-30 20:25:04Z dcollins $
*/
public class MGRSAttributesPanel extends JPanel
{
// Logical components.
private final MGRSGraticuleLayer layer;
// UI components.
private JList itemList;
private JComboBox maxResolutionComboBox;
private JButton saveStateButton;
private JButton loadStateButton;
private JPanel cardPanel;
private CardLayout cardLayout;
private Map<String, Component> graticuleAttribPanelMap = new HashMap<String, Component>();
// Helper properties.
private boolean ignoreLayerEvents = false;
private boolean ignoreUIEvents = false;
private String[] ALL_GRATICULE_TYPES = new String[] {
UTMGraticuleLayer.GRATICULE_UTM,
MGRSGraticuleLayer.GRATICULE_UTM_GRID,
MGRSGraticuleLayer.GRATICULE_100000M,
MGRSGraticuleLayer.GRATICULE_10000M,
MGRSGraticuleLayer.GRATICULE_1000M,
MGRSGraticuleLayer.GRATICULE_100M,
MGRSGraticuleLayer.GRATICULE_10M,
MGRSGraticuleLayer.GRATICULE_1M
};
private String[] MGRS_GRATICULE_TYPES = new String[] {
MGRSGraticuleLayer.GRATICULE_UTM_GRID,
MGRSGraticuleLayer.GRATICULE_100000M,
MGRSGraticuleLayer.GRATICULE_10000M,
MGRSGraticuleLayer.GRATICULE_1000M,
MGRSGraticuleLayer.GRATICULE_100M,
MGRSGraticuleLayer.GRATICULE_10M,
MGRSGraticuleLayer.GRATICULE_1M
};
public MGRSAttributesPanel(MGRSGraticuleLayer mgrsGraticuleLayer)
{
if (mgrsGraticuleLayer == null)
{
String message = Logging.getMessage("nullValue.LayerIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.layer = mgrsGraticuleLayer;
this.layer.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
onLayerPropertyChanged(event);
}
});
init();
}
private void init()
{
// Initialize UI components.
makeComponents();
// Initialize UI layout.
layoutComponents();
// Update UI state to reflect the current layer state.
updateComponents();
String selectedType = MGRSGraticuleLayer.GRATICULE_UTM_GRID;
this.itemList.setSelectedValue(selectedType, true);
this.cardLayout.show(this.cardPanel, selectedType);
}
public final MGRSGraticuleLayer getLayer()
{
return this.layer;
}
public static JDialog showDialog(Component component, String title, MGRSGraticuleLayer mgrsGraticuleLayer)
{
if (mgrsGraticuleLayer == null)
{
String message = Logging.getMessage("nullValue.LayerIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
JDialog dialog;
if (component != null && component instanceof Dialog)
{
dialog = new JDialog((Dialog) component);
}
else if (component != null && component instanceof Frame)
{
dialog = new JDialog((Frame) component);
}
else
{
dialog = new JDialog();
}
if (title != null)
{
dialog.setTitle(title);
}
MGRSAttributesPanel panel = new MGRSAttributesPanel(mgrsGraticuleLayer);
dialog.getContentPane().setLayout(new BorderLayout());
dialog.getContentPane().add(panel, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);
return dialog;
}
public String getSelectedGraticule()
{
Object selectedValue = this.itemList.getSelectedValue();
return selectedValue != null ? selectedValue.toString() : null;
}
public void setSelectedGraticule(String graticuleType)
{
if (graticuleType == null)
{
String message = Logging.getMessage("nullValue.StringIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.itemList.setSelectedValue(graticuleType, true);
this.cardLayout.show(this.cardPanel, graticuleType);
}
private void onListSelectionChanged(ListSelectionEvent event)
{
if (event != null)
{
Object selectedValue = this.itemList.getSelectedValue();
this.cardLayout.show(this.cardPanel, selectedValue.toString());
}
}
private void onMaxResolutionChanged(ActionEvent event)
{
if (event != null)
{
if (!this.ignoreUIEvents)
{
updateLayer();
}
}
}
private void onSaveStatePressed(ActionEvent event)
{
if (event == null)
return;
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
int resultVal = fc.showSaveDialog(this);
if (resultVal != JFileChooser.APPROVE_OPTION)
return;
File file = fc.getSelectedFile();
if (file == null)
return;
try
{
String stateInXml = this.layer.getRestorableState();
saveString(stateInXml, file);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void onLoadStatePressed(ActionEvent event)
{
if (event == null)
return;
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
int resultVal = fc.showOpenDialog(this);
if (resultVal != JFileChooser.APPROVE_OPTION)
return;
File file = fc.getSelectedFile();
if (file == null)
return;
try
{
String stateInXml = loadString(file);
this.layer.restoreState(stateInXml);
this.layer.firePropertyChange(AVKey.LAYER, null, this.layer);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void onPanelStateChanged(PropertyChangeEvent event, String graticuleType)
{
if (event != null && graticuleType != null)
{
if (!this.ignoreUIEvents)
{
if (//event.getPropertyName().equals(GraticuleAttributesPanel.LINE_ENABLED_PROPERTY)
event.getPropertyName().equals(GraticuleAttributesPanel.LINE_COLOR_PROPERTY)
|| event.getPropertyName().equals(GraticuleAttributesPanel.LINE_WIDTH_PROPERTY)
|| event.getPropertyName().equals(GraticuleAttributesPanel.LINE_STYLE_PROPERTY)
|| event.getPropertyName().equals(GraticuleAttributesPanel.LABEL_ENABLED_PROPERTY)
|| event.getPropertyName().equals(GraticuleAttributesPanel.LABEL_COLOR_PROPERTY)
|| event.getPropertyName().equals(GraticuleAttributesPanel.LABEL_FONT_PROPERTY))
{
updateLayer();
}
}
}
}
private void updateLayer()
{
this.ignoreLayerEvents = true;
try
{
if (this.layer != null)
{
this.layer.setMaximumGraticuleResolution(this.maxResolutionComboBox.getSelectedItem().toString());
for (Map.Entry<String, Component> entry : this.graticuleAttribPanelMap.entrySet())
{
if (entry.getKey() != null && entry.getValue() != null)
{
if (entry.getValue() instanceof GraticuleAttributesPanel)
{
updateLayerState((GraticuleAttributesPanel) entry.getValue(), entry.getKey());
}
}
}
}
}
finally
{
this.ignoreLayerEvents = false;
}
}
private void updateLayerState(GraticuleAttributesPanel attributesPanel, String graticuleType)
{
if (this.layer != null && attributesPanel != null && graticuleType != null)
{
//this.layer.setDrawGraticule(attributesPanel.isLineEnableSelected(), graticuleType);
this.layer.setGraticuleLineColor(attributesPanel.getSelectedLineColor(), graticuleType);
this.layer.setGraticuleLineWidth(attributesPanel.getSelectedLineWidth(), graticuleType);
this.layer.setGraticuleLineStyle(attributesPanel.getSelectedLineStyle(), graticuleType);
this.layer.setDrawLabels(attributesPanel.isLabelEnableSelected(), graticuleType);
this.layer.setLabelColor(attributesPanel.getSelectedLabelColor(), graticuleType);
this.layer.setLabelFont(attributesPanel.getSelectedLabelFont(), graticuleType);
this.layer.firePropertyChange(AVKey.LAYER, null, this.layer);
}
}
private void onLayerPropertyChanged(PropertyChangeEvent event)
{
if (event != null)
{
if (!this.ignoreLayerEvents)
{
updateComponents();
}
}
}
private void updateComponents()
{
this.ignoreUIEvents = true;
try
{
if (this.layer != null)
{
this.maxResolutionComboBox.setSelectedItem(layer.getMaximumGraticuleResolution());
}
for (Map.Entry<String, Component> entry : this.graticuleAttribPanelMap.entrySet())
{
if (entry.getKey() != null && entry.getValue() != null)
{
if (entry.getValue() instanceof GraticuleAttributesPanel)
{
updatePanelState((GraticuleAttributesPanel) entry.getValue(), entry.getKey());
}
}
}
}
finally
{
this.ignoreUIEvents = false;
}
}
private void updatePanelState(GraticuleAttributesPanel panel, String graticuleType)
{
if (this.layer != null && panel != null && graticuleType != null)
{
panel.setSelectedLineColor(this.layer.getGraticuleLineColor(graticuleType));
panel.setSelectedLineWidth(this.layer.getGraticuleLineWidth(graticuleType));
panel.setSelectedLineStyle(this.layer.getGraticuleLineStyle(graticuleType));
panel.setLabelEnableSelected(this.layer.isDrawLabels(graticuleType));
panel.setSelectedLabelColor(this.layer.getLabelColor(graticuleType));
panel.setSelectedLabelFont(this.layer.getLabelFont(graticuleType));
}
}
private static String loadString(File file) throws IOException
{
String s = null;
FileReader reader = null;
try
{
reader = new FileReader(file);
StringBuilder sb = new StringBuilder();
int numRead;
char[] buffer = new char[2048];
while ((numRead = reader.read(buffer, 0, buffer.length)) != -1)
{
sb.append(buffer, 0, numRead);
}
s = sb.toString();
}
finally
{
try
{
if (reader != null)
reader.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
return s;
}
private static void saveString(String s, File file) throws IOException
{
FileWriter writer = null;
try
{
if (s != null && file != null)
{
writer = new FileWriter(file);
writer.write(s);
}
}
finally
{
try
{
if (writer != null)
writer.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
private void makeComponents()
{
this.itemList = new JList(ALL_GRATICULE_TYPES);
this.itemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ListCellRenderer originalRenderer = this.itemList.getCellRenderer();
this.itemList.setCellRenderer(new GraticuleTypeListRenderer(originalRenderer, null));
this.itemList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
onListSelectionChanged(event);
}
});
this.saveStateButton = new JButton("Save State");
this.saveStateButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
onSaveStatePressed(event);
}
});
this.loadStateButton = new JButton("Load State");
this.loadStateButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
onLoadStatePressed(event);
}
});
this.maxResolutionComboBox = new JComboBox(MGRS_GRATICULE_TYPES);
originalRenderer = this.maxResolutionComboBox.getRenderer();
this.maxResolutionComboBox.setRenderer(new GraticuleTypeListRenderer(originalRenderer, null));
this.maxResolutionComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
onMaxResolutionChanged(event);
}
});
this.cardLayout = new CardLayout();
this.cardPanel = new JPanel();
this.cardPanel.setLayout(this.cardLayout);
for (String type : ALL_GRATICULE_TYPES)
{
Component panel = makeGraticulePanel(type);
this.graticuleAttribPanelMap.put(type, panel);
}
}
private Component makeGraticulePanel(final String graticuleType)
{
if (graticuleType == null)
{
String message = Logging.getMessage("nullValue.StringIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
GraticuleAttributesPanel panel = new GraticuleAttributesPanel();
panel.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
onPanelStateChanged(event, graticuleType);
}
});
return panel;
}
private void layoutComponents()
{
setLayout(new BorderLayout());
//---------- Graticule Item List ----------//
{
Box box = Box.createVerticalBox();
box.setBorder(new EmptyBorder(30, 20, 20, 5));
JScrollPane itemScrollPane = new JScrollPane(this.itemList);
itemScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(itemScrollPane);
box.add(Box.createVerticalStrut(20));
JLabel label = new JLabel("Maximum Resolution");
label.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(label);
this.maxResolutionComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(this.maxResolutionComboBox);
box.add(Box.createVerticalStrut(20));
this.saveStateButton.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(this.saveStateButton);
this.loadStateButton.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(this.loadStateButton);
box.add(Box.createVerticalGlue());
add(box, BorderLayout.WEST);
}
//---------- Graticule Card Panel ----------//
{
this.cardPanel.setBorder(new EmptyBorder(30, 5, 20, 20));
for (Map.Entry<String, Component> entry : this.graticuleAttribPanelMap.entrySet())
{
if (entry.getKey() != null && entry.getValue() != null)
{
this.cardPanel.add(entry.getValue(), entry.getKey());
}
}
add(this.cardPanel, BorderLayout.CENTER);
}
}
private static String getGraticuleLabel(String graticuleType)
{
String labelText = null;
if (UTMGraticuleLayer.GRATICULE_UTM.equals(graticuleType))
labelText = "Global UTM";
else if (MGRSGraticuleLayer.GRATICULE_UTM_GRID.equals(graticuleType))
labelText = "UTM Grid";
else if (MGRSGraticuleLayer.GRATICULE_100000M.equals(graticuleType))
labelText = "100km";
else if (MGRSGraticuleLayer.GRATICULE_10000M.equals(graticuleType))
labelText = "10km";
else if (MGRSGraticuleLayer.GRATICULE_1000M.equals(graticuleType))
labelText = "1km";
else if (MGRSGraticuleLayer.GRATICULE_100M.equals(graticuleType))
labelText = "100m";
else if (MGRSGraticuleLayer.GRATICULE_10M.equals(graticuleType))
labelText = "10m";
else if (MGRSGraticuleLayer.GRATICULE_1M.equals(graticuleType))
labelText = "1m";
return labelText;
}
private Icon getIcon(String path)
{
Icon icon = null;
try
{
URL url = getClass().getResource(path);
if (url != null)
{
icon = new ImageIcon(url);
}
}
catch (Exception e)
{
String message = "Exception while loading icon";
Logging.logger().log(java.util.logging.Level.WARNING, message, e);
}
return icon;
}
private static class GraticuleTypeListRenderer implements ListCellRenderer
{
private ListCellRenderer delegate;
private Icon icon;
public GraticuleTypeListRenderer(ListCellRenderer delegate, Icon icon)
{
this.delegate = delegate;
this.icon = icon;
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
Component c = this.delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c != null && c instanceof JLabel)
{
JLabel label = (JLabel) c;
Font font = label.getFont();
if (font != null)
{
label.setFont(font.deriveFont(Font.BOLD));
}
if (this.icon != null)
{
label.setIcon(this.icon);
}
if (value != null && value instanceof String)
{
String graticuleType = (String) value;
String labelText = getGraticuleLabel(graticuleType);
label.setText(labelText);
}
}
return c;
}
}
}