Package com.bbn.openmap.omGraphics

Source Code of com.bbn.openmap.omGraphics.EditableOMRangeRings

// **********************************************************************
//
// <copyright>
//
//  BBN Technologies
//  10 Moulton Street
//  Cambridge, MA 02138
//  (617) 873-8000
//
//  Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/omGraphics/EditableOMRangeRings.java,v $
// $RCSfile: EditableOMRangeRings.java,v $
// $Revision: 1.6.2.10 $
// $Date: 2008/01/29 02:21:01 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.omGraphics;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.text.DecimalFormat;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.border.EmptyBorder;

import com.bbn.openmap.Environment;
import com.bbn.openmap.I18n;
import com.bbn.openmap.gui.GridBagToolBar;
import com.bbn.openmap.proj.Length;
import com.bbn.openmap.util.Debug;

/**
*/
public class EditableOMRangeRings extends EditableOMCircle {

    // TODO need to update the memory mechanism between OMRangeRings that are
    // being edited/created so that statics aren't being used. Maybe add a
    // properties object to DrawingAttributes and have the memory there.
    protected static int lastInterval;
    protected static Length lastUnit;
    protected static boolean snapToInterval = false;

    /**
     * Create the EditableOMRangeRings, setting the state machine to create the
     * circle off of the gestures.
     */
    public EditableOMRangeRings() {
        createGraphic(null);
    }

    /**
     * Create an EditableOMRangeRings with the circleType and renderType
     * parameters in the GraphicAttributes object.
     */
    public EditableOMRangeRings(GraphicAttributes ga) {
        createGraphic(ga);
    }

    /**
     * Create the EditableOMRangeRings with an OMCircle already defined, ready
     * for editing.
     *
     * @param omc OMCircle that should be edited.
     */
    public EditableOMRangeRings(OMRangeRings omc) {
        setGraphic(omc);
    }

    /**
     * Create and set the graphic within the state machine. The
     * GraphicAttributes describe the type of circle to create.
     */
    public void createGraphic(GraphicAttributes ga) {
        init();
        stateMachine.setUndefined();
        int renderType = OMGraphic.RENDERTYPE_LATLON;

        if (ga != null) {
            renderType = ga.getRenderType();
        }

        if (Debug.debugging("eomc")) {
            Debug.output("EditableOMRangeRings.createGraphic(): rendertype = "
                    + renderType);
        }

        circle = new OMRangeRings(90f, -180f, 0f);

        if (ga != null) {
            ga.setTo(circle, true);
        }
    }

    /**
     * Modifies the gui to not include line type adjustments, and adds widgets
     * to control range ring settings.
     *
     * @param graphicAttributes the GraphicAttributes to use to get the GUI
     *        widget from to control those parameters for this EOMG.
     * @return java.awt.Component to use to control parameters for this EOMG.
     */
    public Component getGUI(GraphicAttributes graphicAttributes) {
        Debug.message("eomg", "EditableOMRangeRings.getGUI");
        if (graphicAttributes != null) {
            JPanel panel = graphicAttributes.getColorAndLineGUI();
            panel.add(getRangeRingGUI());
            return panel;
        } else {
            return getRangeRingGUI();
        }
    }

    public void updateInterval(int val) {
        ((OMRangeRings) circle).setInterval(val);
        lastInterval = val;
        if (intervalField != null) {
            intervalField.setText(Integer.toString(val));
        }

        if (snapToInterval) {
            setRadius(circle.getRadius());
        }
        redraw(null, true);
    }

    public void updateInterval(String intervalStr) {
        int oldValue = ((OMRangeRings) circle).getInterval();
        int value = interpretValue(intervalStr);

        if (value <= 0) {
            value = oldValue;
        }

        updateInterval(value);
    }

    public int interpretValue(String intervalStr) {
        int value = -1;
        try {
            if (intervalStr.toLowerCase().endsWith("m")) {
                intervalStr = intervalStr.substring(0, intervalStr.length() - 1);
                value = (int) df.parse(intervalStr).intValue() * 1000000;
            } else if (intervalStr.toLowerCase().endsWith("k")) {
                intervalStr = intervalStr.substring(0, intervalStr.length() - 1);
                value = df.parse(intervalStr).intValue() * 1000;
            } else if (intervalStr.trim().equals("")) {
                // do nothing
            } else {
                value = df.parse(intervalStr).intValue();
            }
        } catch (java.text.ParseException e) {
            Debug.error("RangeRing interval value not valid: " + intervalStr);
        } catch (NumberFormatException e) {
            Debug.error("RangeRing interval value not valid: " + intervalStr);
        }
        return value;
    }

    protected JTextField intervalField = null;
    protected JToolBar rrToolBar = null;
    protected transient DecimalFormat df = new DecimalFormat();
    protected I18n i18n = Environment.getI18n();

    protected JToolBar getRangeRingGUI() {
        if (rrToolBar == null) {
            rrToolBar = new GridBagToolBar();
            rrToolBar.setFloatable(false);
            rrToolBar.setMargin(new Insets(0, 1, 0, 1));

            configureRangeRings();
            intervalField = makeIntervalField();
            rrToolBar.add(intervalField);

            // JSlider intervalSlide = new JSlider(
            // JSlider.HORIZONTAL, 1/*min*/, 200/*max*/,
            // ((OMRangeRings)circle).getInterval()/*inital*/);
            // java.util.Hashtable dict = new java.util.Hashtable();
            // dict.put(new Integer(1), new JLabel("1"));
            // dict.put(new Integer(50), new JLabel("50"));
            // dict.put(new Integer(100), new JLabel("100"));
            // dict.put(new Integer(150), new JLabel("150"));
            // dict.put(new Integer(200), new JLabel("200"));
            // intervalSlide.setLabelTable(dict);
            // intervalSlide.setPaintLabels(true);
            // intervalSlide.setMajorTickSpacing(10);
            // intervalSlide.setPaintTicks(true);
            // intervalSlide.setSnapToTicks(false);
            // intervalSlide.addChangeListener(new ChangeListener() {
            // public void stateChanged(ChangeEvent ce) {
            // JSlider slider = (JSlider) ce.getSource();
            // if (slider.getValueIsAdjusting()) {
            // ((OMRangeRings)circle).setInterval(slider.getValue());
            // }
            // }
            // });

            rrToolBar.add(makeUnitsCombo());
            rrToolBar.add(makeSnapCheckBox());
        }
        return rrToolBar;
    }

    private void configureRangeRings() {
        ((OMRangeRings) circle).setInterval(getInterval());
        ((OMRangeRings) circle).setIntervalUnits(getUnits());
    }

    private int getInterval() {
        return (!isNewRing()) ? ((OMRangeRings) circle).getInterval()
                : haveUserSpecifiedValue() ? lastInterval
                        : OMRangeRings.DEFAULT_INTERVAL;
    }

    private Length getUnits() {
        return (!isNewRing()) ? ((OMRangeRings) circle).getIntervalUnits()
                : haveUserSpecifiedValue() ? lastUnit : null;
    }

    private boolean isNewRing() {
        // we rely on interval units not being initialized during construction
        return (((OMRangeRings) circle).getIntervalUnits() == null);
    }

    private boolean haveUserSpecifiedValue() {
        // lastUnit is not null if the user made a selection with the comboBox
        return (lastUnit != null);
    }

    private JTextField makeIntervalField() {
        JTextField field = new JTextField(Integer.toString(((OMRangeRings) circle).getInterval()), 5);
        field.setMargin(new Insets(0, 1, 0, 1));
        // without minimum size set, field can be too small to use
        field.setMinimumSize(new Dimension(40, 18));
        field.setHorizontalAlignment(JTextField.RIGHT);
        field.setToolTipText(i18n.get(this,
                "intervalField.tooltip",
                "Value for interval between rings."));
        field.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                updateInterval(((JTextField) (ae.getSource())).getText());
            }
        });
        // Users forget to hit Enter, which is required for an action event,
        // then wonder why the rings they draw don't have the desired value.
        // Adding a focus listener addresses this issue.
        field.addFocusListener(new FocusAdapter() {
            public void focusLost(FocusEvent event) {
                if (!event.isTemporary()) {
                    updateInterval(((JTextField) (event.getSource())).getText());
                }
            }
        });
        return field;
    }

    private JComboBox makeUnitsCombo() {
        Length[] available = Length.getAvailable();
        String[] unitStrings = new String[available.length + 1];

        String current = null;
        Length l = ((OMRangeRings) circle).getIntervalUnits();
        if (l != null) {
            current = l.toString();
        }

        int currentIndex = unitStrings.length - 1;

        for (int i = 0; i < available.length; i++) {
            unitStrings[i] = available[i].toString();
            if (current != null && unitStrings[i].equals(current)) {
                currentIndex = i;
            }
        }
        unitStrings[unitStrings.length - 1] = i18n.get(this,
                "unitStrings.concentric",
                "concentric");

        JComboBox combo = new JComboBox(unitStrings);
        combo.setBorder(new EmptyBorder(0, 1, 0, 1));
        combo.setSelectedIndex(currentIndex);
        combo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JComboBox jcb = (JComboBox) e.getSource();
                OMRangeRings rr = (OMRangeRings) circle;
                Length newLength = Length.get((String) jcb.getSelectedItem());
                Length oldLength = rr.getIntervalUnits();

                /*
                 * If newLength is not null and oldLength is not null, just
                 * translate the distance that is current specified. If
                 * newLength is null, then find out how many rings are on the
                 * range ring and set the interval to that. If oldLength is
                 * null, find out the radius and divide it by the number of
                 * rings - 1.
                 */

                int value = interpretValue(intervalField.getText());
                if (value <= 0) {
                    value = 4;
                }

                if (newLength != null && oldLength != null) {
                    value = (int) newLength.fromRadians(oldLength.toRadians(value));
                } else {
                    int numSubCircles;
                    if (rr.subCircles == null || rr.subCircles.length == 0) {
                        numSubCircles = 1;
                    } else {
                        numSubCircles = rr.subCircles.length;
                    }

                    if (newLength == null) {
                        value = numSubCircles;
                    } else if (oldLength == null) {
                        value = (int) Math.ceil(newLength.fromRadians(Length.DECIMAL_DEGREE.toRadians(rr.getRadius()))
                                / numSubCircles);
                    }
                }

                ((OMRangeRings) circle).setIntervalUnits(newLength);
                lastUnit = newLength;
                updateInterval(value);
            }
        });
        return combo;
    }

    private JCheckBox makeSnapCheckBox() {
        String snapText = i18n.get(this, "snapToInterval", "Snap");
        JCheckBox snapBox = new JCheckBox(snapText, isSnapToInterval());
        snapText = i18n.get(this,
                "snapToInterval",
                I18n.TOOLTIP,
                "Round radius to nearest interval value.");
        snapBox.setToolTipText(snapText);
        snapBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                setSnapToInterval(((JCheckBox) ae.getSource()).isSelected());
                if (snapToInterval) {
                    setRadius(circle.getRadius());
                }
                redraw(null, true);
            }
        });
        return snapBox;
    }

    protected boolean drawLabelsHolder = true;

    /**
     * A convenience method that gives an EditableOMGraphic a chance to modify
     * the OMGraphic so it can be drawn quickly, by turning off labels, etc,
     * right before the XORpainting happens. The OMGraphic should be configured
     * so that the render method does the least amount of painting possible.
     * Note that the DrawingAttributes for the OMGraphic have already been set
     * to DrawingAttributes.DEFAULT (black line, clear fill).
     */
    protected void modifyOMGraphicForEditRender() {
        OMRangeRings omrr = (OMRangeRings) getGraphic();
        drawLabelsHolder = omrr.getDrawLabels();
        omrr.setDrawLabels(false);
    }

    /**
     * A convenience method that gives an EditableOMGraphic a chance to reset
     * the OMGraphic so it can be rendered normally, after it has been modified
     * for quick paints. The DrawingAttributes for the OMGraphic have already
     * been reset to their normal settings, from the DrawingAttributes.DEFAULT
     * settings that were used for the quick paint.
     */
    protected void resetOMGraphicAfterEditRender() {
        ((OMRangeRings) getGraphic()).setDrawLabels(drawLabelsHolder);
    }

    public boolean isSnapToInterval() {
        return snapToInterval;
    }

    public void setSnapToInterval(boolean sti) {
        snapToInterval = sti;
    }

    protected void setRadius(float radius) {
        if (circle != null) {
            if (snapToInterval) {
                OMRangeRings rr = (OMRangeRings) circle;
                Length units = rr.getIntervalUnits();
                if (units != null) {
                    float rds = units.fromRadians(Length.DECIMAL_DEGREE.toRadians(radius));
                    radius = Math.round(rds / rr.getInterval())
                            * rr.getInterval();
                    radius = Length.DECIMAL_DEGREE.fromRadians(units.toRadians(radius));
                }
            }
            circle.setRadius(radius);
        }
    }
}
TOP

Related Classes of com.bbn.openmap.omGraphics.EditableOMRangeRings

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.