/* 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.layers.Earth.MGRSGraticuleLayer; import gov.nasa.worldwind.util.Logging; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; import javax.swing.border.CompoundBorder; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; /** * @author dcollins * @version $Id: GraticuleAttributesPanel.java 4708 2008-03-15 09:41:26Z dcollins $ */ public class GraticuleAttributesPanel extends JPanel { // Line attribute components. private JPanel linePanel; //private JCheckBox lineEnabled; private ColorPanel lineColorPanel; private JSlider lineWidthSlider; private JSpinner lineWidthSpinner; private SpinnerNumberModel lineWidthSpinnerModel; private JComboBox lineStyle; // Label attribute components. private JPanel labelPanel; private ColorPanel labelColorPanel; private JCheckBox labelEnabled; private JComboBox labelFontName; private JComboBox labelFontStyle; private JComboBox labelFontSize; private static final int MIN_LINE_WIDTH = 1; private static final int MAX_LINE_WIDTH = 8; private static final int LINE_WIDTH_SCALE = 16; //public static final String LINE_ENABLED_PROPERTY = "LineEnabled"; public static final String LINE_COLOR_PROPERTY = "LineColor"; public static final String LINE_WIDTH_PROPERTY = "LineWidth"; public static final String LINE_STYLE_PROPERTY = "LineStyle"; public static final String LABEL_ENABLED_PROPERTY = "LabelEnabled"; public static final String LABEL_COLOR_PROPERTY = "LabelColor"; public static final String LABEL_FONT_PROPERTY = "LabelFont"; public GraticuleAttributesPanel() { makeComponents(); layoutComponents(); } //public boolean isLineEnableSelected() //{ // return this.lineEnabled.isSelected(); //} // //public void setLineEnableSelected(boolean b) //{ // this.lineEnabled.setSelected(b); //} public Color getSelectedLineColor() { return this.lineColorPanel.getColor(); } public void setSelectedLineColor(Color value) { if (value == null) { String message = Logging.getMessage("nullValue.ColorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.lineColorPanel.setColor(value); } public double getSelectedLineWidth() { return this.lineWidthSpinnerModel.getNumber().doubleValue(); } public void setSelectedLineWidth(double value) { setLineWidthControls(value); } public String getSelectedLineStyle() { return this.lineStyle.getSelectedItem().toString(); } public void setSelectedLineStyle(String value) { if (value == null) { String message = Logging.getMessage("nullValue.StringIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.lineStyle.setSelectedItem(value); } public boolean isLabelEnableSelected() { return this.labelEnabled.isSelected(); } public void setLabelEnableSelected(boolean b) { this.labelEnabled.setSelected(b); } public Color getSelectedLabelColor() { return this.labelColorPanel.getColor(); } public void setSelectedLabelColor(Color value) { if (value == null) { String message = Logging.getMessage("nullValue.ColorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.labelColorPanel.setColor(value); } public Font getSelectedLabelFont() { return makeFontFromControls(); } public void setSelectedLabelFont(Font value) { if (value == null) { String message = Logging.getMessage("nullValue.FontIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } setFontControls(value); } //private void onLineEnableChanged(ItemEvent event) //{ // if (event != null) // { // firePropertyChange(LINE_ENABLED_PROPERTY, null, event.getStateChange() == ItemEvent.SELECTED); // } //} private void onLineColorChanged(PropertyChangeEvent event) { if (event != null) { firePropertyChange(LINE_COLOR_PROPERTY, null, event.getNewValue()); } } private void onLineWidthSliderChanged(ChangeEvent event) { if (event != null) { double width = this.lineWidthSlider.getValue() / (double) LINE_WIDTH_SCALE; this.lineWidthSpinner.setValue(width); firePropertyChange(LINE_WIDTH_PROPERTY, null, width); } } private void onLineWidthSpinnerChanged(ChangeEvent event) { if (event != null) { double width = this.lineWidthSpinnerModel.getNumber().doubleValue(); this.lineWidthSlider.setValue((int) (width * LINE_WIDTH_SCALE)); firePropertyChange(LINE_WIDTH_PROPERTY, null, width); } } private void onLineStyleChanged(ActionEvent event) { if (event != null) { String style = this.lineStyle.getSelectedItem().toString(); firePropertyChange(LINE_STYLE_PROPERTY, null, style); } } private void onLabelEnableChanged(ItemEvent event) { if (event != null) { firePropertyChange(LABEL_ENABLED_PROPERTY, null, event.getStateChange() == ItemEvent.SELECTED); } } private void onLabelColorChanged(PropertyChangeEvent event) { if (event != null) { firePropertyChange(LABEL_COLOR_PROPERTY, null, event.getNewValue()); } } private void onLabelFontChanged(ActionEvent event) { if (event != null) { Font font = makeFontFromControls(); firePropertyChange(LABEL_FONT_PROPERTY, null, font); } } private void setLineWidthControls(double width) { this.lineWidthSlider.setValue((int) (width * LINE_WIDTH_SCALE)); this.lineWidthSpinner.setValue(width); } private Font makeFontFromControls() { StringBuilder sb = new StringBuilder(); sb.append(this.labelFontName.getSelectedItem()); sb.append("-"); sb.append(this.labelFontStyle.getSelectedItem()); sb.append("-"); sb.append(this.labelFontSize.getSelectedItem()); return Font.decode(sb.toString()); } private void setFontControls(Font font) { if (font == null) { String message = Logging.getMessage("nullValue.FontIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Apply the font name. this.labelFontName.setSelectedItem(font.getName()); // Apply the font style. if ((font.getStyle() & Font.BOLD) != 0) this.labelFontStyle.setSelectedItem("Bold"); else if ((font.getStyle() & Font.ITALIC) != 0) this.labelFontStyle.setSelectedItem("Italic"); else if ((font.getStyle() & (Font.BOLD|Font.ITALIC)) != 0) this.labelFontStyle.setSelectedItem("BoldItalic"); else this.labelFontStyle.setSelectedItem("Plain"); // Apply the font size. this.labelFontSize.setSelectedItem(String.format("%d", font.getSize())); } private void makeComponents() { //---------- Line Properties ----------// { String[] lineStyles = new String[] { MGRSGraticuleLayer.LINE_STYLE_SOLID, MGRSGraticuleLayer.LINE_STYLE_DASHED, MGRSGraticuleLayer.LINE_STYLE_DOTTED }; this.linePanel = new JPanel(); //this.lineEnabled = new JCheckBox("Show Graticule"); this.lineColorPanel = new ColorPanel(); //noinspection PointlessArithmeticExpression this.lineWidthSlider = new JSlider( MIN_LINE_WIDTH * LINE_WIDTH_SCALE, // min MAX_LINE_WIDTH * LINE_WIDTH_SCALE); // max this.lineWidthSlider.setMajorTickSpacing(LINE_WIDTH_SCALE); this.lineWidthSlider.setMinorTickSpacing(LINE_WIDTH_SCALE / 4); this.lineWidthSlider.setPaintTicks(true); this.lineWidthSlider.setSnapToTicks(true); this.lineWidthSpinnerModel = new SpinnerNumberModel( (double) MIN_LINE_WIDTH, // value (double) MIN_LINE_WIDTH, // min (double) MAX_LINE_WIDTH, // max 4.0 / (double) LINE_WIDTH_SCALE); // stepsize this.lineWidthSpinner = new JSpinner(this.lineWidthSpinnerModel); this.lineStyle = new JComboBox(lineStyles); ListCellRenderer originalRenderer = this.lineStyle.getRenderer(); this.lineStyle.setRenderer(new LineStyleRenderer(originalRenderer)); //this.lineEnabled.addItemListener(new ItemListener() { // public void itemStateChanged(ItemEvent event) { // onLineEnableChanged(event); // } //}); this.lineColorPanel.addColorChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { onLineColorChanged(event); } }); this.lineWidthSlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { onLineWidthSliderChanged(event); } }); this.lineWidthSpinner.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { onLineWidthSpinnerChanged(event); } }); this.lineStyle.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { onLineStyleChanged(event); } }); } //---------- Label Properties ----------// { this.labelPanel = new JPanel(); this.labelEnabled = new JCheckBox("Show Labels"); this.labelColorPanel = new ColorPanel(); this.labelFontName = new JComboBox(new String[] {"Arial", "SansSerif", "Serif", "Courier", "Times", "Helvetica", "Trebuchet", "Tahoma"}); this.labelFontStyle = new JComboBox(new String[] {"Plain", "Bold", "Italic", "BoldItalic"}); this.labelFontSize = new JComboBox(new String[] {"8", "10", "12", "14", "16", "18", "20", "24", "28", "34", "48", "64"}); this.labelEnabled.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent event) { onLabelEnableChanged(event); } }); this.labelColorPanel.addColorChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { onLabelColorChanged(event); } }); this.labelFontName.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { onLabelFontChanged(event); } }); this.labelFontStyle.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { onLabelFontChanged(event); } }); this.labelFontSize.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { onLabelFontChanged(event); } }); } } private void layoutComponents() { setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); //---------- Line Properties ----------// { this.linePanel.setLayout(new BoxLayout(this.linePanel, BoxLayout.PAGE_AXIS)); this.linePanel.setBorder(new CompoundBorder(new TitledBorder("Graticule"), new EmptyBorder(10, 10, 10, 10))); //this.lineEnabled.setAlignmentX(Component.LEFT_ALIGNMENT); //this.linePanel.add(this.lineEnabled); //this.linePanel.add(Box.createVerticalStrut(10)); this.lineColorPanel.setAlignmentX(Component.LEFT_ALIGNMENT); this.linePanel.add(this.lineColorPanel); this.linePanel.add(Box.createVerticalStrut(10)); Box hbox = Box.createHorizontalBox(); hbox.setAlignmentX(Component.LEFT_ALIGNMENT); hbox.add(this.lineWidthSlider); hbox.add(this.lineWidthSpinner); hbox.add(Box.createHorizontalGlue()); this.linePanel.add(hbox); this.linePanel.add(Box.createVerticalStrut(10)); this.lineStyle.setAlignmentX(Component.LEFT_ALIGNMENT); this.linePanel.add(this.lineStyle); } this.linePanel.setAlignmentX(Component.LEFT_ALIGNMENT); add(this.linePanel); add(Box.createVerticalStrut(20)); //---------- Label Properties ----------// { this.labelPanel.setLayout(new BoxLayout(this.labelPanel, BoxLayout.PAGE_AXIS)); this.labelPanel.setBorder(new CompoundBorder(new TitledBorder("Labels"), new EmptyBorder(10, 10, 10, 10))); this.labelEnabled.setAlignmentX(Component.LEFT_ALIGNMENT); this.labelPanel.add(this.labelEnabled); this.labelPanel.add(Box.createVerticalStrut(10)); this.labelColorPanel.setAlignmentX(Component.LEFT_ALIGNMENT); this.labelPanel.add(this.labelColorPanel); this.labelPanel.add(Box.createVerticalStrut(10)); Box hbox = Box.createHorizontalBox(); hbox.setAlignmentX(Component.LEFT_ALIGNMENT); hbox.add(this.labelFontName); hbox.add(this.labelFontStyle); hbox.add(this.labelFontSize); this.labelPanel.add(hbox); } this.labelPanel.setAlignmentX(Component.LEFT_ALIGNMENT); add(this.labelPanel); add(Box.createVerticalGlue()); } private static String getLineStyleLabel(String lineStyle) { String labelText = null; if (MGRSGraticuleLayer.LINE_STYLE_SOLID.equals(lineStyle)) labelText = "Solid"; else if (MGRSGraticuleLayer.LINE_STYLE_DASHED.equals(lineStyle)) labelText = "Dashed"; else if (MGRSGraticuleLayer.LINE_STYLE_DOTTED.equals(lineStyle)) labelText = "Dotted"; return labelText; } private static class LineStyleRenderer implements ListCellRenderer { private ListCellRenderer delegate; public LineStyleRenderer(ListCellRenderer delegate) { this.delegate = delegate; } 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; if (value != null && value instanceof String) { String lineStyle = (String) value; String labelText = getLineStyleLabel(lineStyle); label.setText(labelText); } } return c; } } private static class ColorPanel extends JPanel { private JLabel colorLabel; private JButton colorButton; private JColorChooser colorChooser; private JDialog colorChooserDialog; private JSlider opacitySlider; private Color lastSelectedColor = null; private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); public ColorPanel() { makeComponents(); layoutComponents(); } public void addColorChangeListener(PropertyChangeListener propertyChangeListener) { this.changeSupport.addPropertyChangeListener(propertyChangeListener); } public void removeColorChangeListener(PropertyChangeListener propertyChangeListener) { this.changeSupport.removePropertyChangeListener(propertyChangeListener); } public void fireColorChanged() { this.changeSupport.firePropertyChange("color", null, makeColorFromControls()); } public Color getColor() { return makeColorFromControls(); } public void setColor(Color color) { if (color == null) { String message = Logging.getMessage("nullValue.ColorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } setColorControls(color); } private Color makeColorFromControls() { Color rgb = this.colorChooser.getColor(); int a = this.opacitySlider.getValue(); return new Color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), a); } private void setColorControls(Color color) { if (color == null) { String message = Logging.getMessage("nullValue.ColorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.colorChooser.setColor(color); this.opacitySlider.setValue(color.getAlpha()); setColorLabel(color); } private void onColorPressed() { this.lastSelectedColor = makeColorFromControls(); this.colorChooserDialog.setVisible(true); } private void onColorChooserOk(ActionEvent event) { if (event != null) { this.lastSelectedColor = null; Color color = makeColorFromControls(); setColorLabel(color); if (color != null) { fireColorChanged(); } } } private void onColorChooserCancel(ActionEvent event) { if (event != null) { Color color = this.lastSelectedColor; if (color != null) { setColorControls(color); fireColorChanged(); } } } private void onColorChooserChanged(ChangeEvent event) { if (event != null) { Color color = makeColorFromControls(); setColorLabel(color); if (color != null) { fireColorChanged(); } } } private void onOpacityChanged(ChangeEvent event) { if (event != null) { Color color = makeColorFromControls(); setColorLabel(color); if (color != null) { fireColorChanged(); } } } private void makeComponents() { this.colorLabel = new JLabel(makeImageIcon(60, 16)); this.colorButton = new JButton("Choose..."); this.colorChooser = new JColorChooser(); // Replace the color "preview panel" with an empty panel. // We will be previewing color changes in the WorldWindow. this.colorChooser.setPreviewPanel(new JPanel()); this.opacitySlider = new JSlider( 1, // min 255); // max this.colorChooserDialog = JColorChooser.createDialog(this, "Choose Graticule Color", true, this.colorChooser, new ActionListener() { public void actionPerformed(ActionEvent event) { onColorChooserOk(event); } }, new ActionListener() { public void actionPerformed(ActionEvent event) { onColorChooserCancel(event); } }); this.colorLabel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent event) { onColorPressed(); } }); this.colorButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { onColorPressed(); } }); this.colorChooser.getSelectionModel().addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { onColorChooserChanged(event); } }); this.opacitySlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { onOpacityChanged(event); } }); } private void setColorLabel(Color color) { if (color != null && this.colorLabel != null && this.colorLabel.getIcon() != null && this.colorLabel.getIcon() instanceof ImageIcon) { ImageIcon icon = (ImageIcon) this.colorLabel.getIcon(); if (icon.getImage() != null) { // We only want to represent the RGB color components // on this label. Color rgb = new Color(color.getRGB()); fillImage(icon.getImage(), rgb); this.colorLabel.repaint(); } } } private void layoutComponents() { setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); Box hbox = Box.createHorizontalBox(); hbox.setAlignmentX(Component.LEFT_ALIGNMENT); this.colorLabel.setBorder(new MatteBorder(1, 1, 1, 1, Color.BLACK)); hbox.add(this.colorLabel); hbox.add(Box.createHorizontalStrut(5)); hbox.add(this.colorButton); add(hbox); add(Box.createVerticalStrut(10)); this.opacitySlider.setAlignmentX(Component.LEFT_ALIGNMENT); add(this.opacitySlider); } } private static ImageIcon makeImageIcon(int width, int height) { ImageIcon icon = null; try { BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); icon = new ImageIcon(bi); } catch (Exception e) { String message = "Exception while creating icon"; Logging.logger().log(java.util.logging.Level.SEVERE, message, e); } return icon; } private static void fillImage(Image image, Color color) { try { Graphics g = image.getGraphics(); g.setColor(color); g.fillRect(0, 0, image.getWidth(null), image.getHeight(null)); } catch (Exception e) { String message = "Exception while drawing to image"; Logging.logger().log(java.util.logging.Level.SEVERE, message, e); } } }