Package com.bbn.openmap.omGraphics

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

// **********************************************************************
//
// <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/EditableOMText.java,v $
// $RCSfile: EditableOMText.java,v $
// $Revision: 1.4.2.5 $
// $Date: 2008/01/29 02:21:01 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.omGraphics;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JToggleButton;

import com.bbn.openmap.Environment;
import com.bbn.openmap.I18n;
import com.bbn.openmap.LatLonPoint;
import com.bbn.openmap.layer.util.stateMachine.State;
import com.bbn.openmap.omGraphics.editable.GraphicEditState;
import com.bbn.openmap.omGraphics.editable.GraphicSelectedState;
import com.bbn.openmap.omGraphics.editable.GraphicSetOffsetState;
import com.bbn.openmap.omGraphics.editable.GraphicUndefinedState;
import com.bbn.openmap.omGraphics.editable.TextStateMachine;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.util.Debug;

/**
* Wrapper class to edit OMText objects. This component is used by the
* OMDrawingTool.
*/
public class EditableOMText extends EditableOMGraphic implements ActionListener {

    protected GrabPoint gpc;
    protected OffsetGrabPoint gpo; // offset

    protected OMText text;

    public final static int CENTER_POINT_INDEX = 0;
    public final static int OFFSET_POINT_INDEX = 1;

    /**
     * For internationalization.
     */
    protected I18n i18n = Environment.getI18n();

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

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

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

    /**
     * Create and initialize the state machine that interprets the
     * modifying gestures/commands, as well as ititialize the grab
     * points. Also allocates the grab point array needed by the
     * EditableOMText.
     */
    public void init() {
        setCanGrabGraphic(false);
        setStateMachine(new TextStateMachine(this));
        gPoints = new GrabPoint[2];
    }

    /**
     * Set the graphic within the state machine. If the graphic is
     * null, then one shall be created, and located off screen until
     * the gestures driving the state machine place it on the map.
     */
    public void setGraphic(OMGraphic graphic) {
        init();
        if (graphic instanceof OMText) {
            text = (OMText) graphic;
            stateMachine.setSelected();
            setGrabPoints(text);
        } else {
            createGraphic(null);
        }
    }

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

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

        switch (renderType) {
        case (OMGraphic.RENDERTYPE_LATLON):
            text = new OMText(90f, -180f, "Text", OMText.JUSTIFY_LEFT);
            break;
        case (OMGraphic.RENDERTYPE_OFFSET):
            text = new OMText(90f, -180f, 0, 0, "Text", OMText.JUSTIFY_LEFT);
            break;
        default:
            text = new OMText(0, 0, "Text", OMText.JUSTIFY_LEFT);
        }

        if (ga != null) {
            ga.setTo(text, true);
            text.setLinePaint(ga.getLinePaint());
        }

        assertGrabPoints();
    }

    /**
     * Get the OMGraphic being created/modified by the EditableOMText.
     */
    public OMGraphic getGraphic() {
        return text;
    }

    /**
     * Attach to the Moving OffsetGrabPoint so if it moves, it will
     * move this EditableOMGraphic with it. EditableOMGraphic version
     * doesn't do anything, each subclass has to decide which of its
     * OffsetGrabPoints should be attached to it.
     */
    public void attachToMovingGrabPoint(OffsetGrabPoint gp) {
        gp.addGrabPoint(gpo);
    }

    /**
     * Detach from a Moving OffsetGrabPoint. The EditableOMGraphic
     * version doesn't do anything, each subclass should remove
     * whatever GrabPoint it would have attached to an
     * OffsetGrabPoint.
     */
    public void detachFromMovingGrabPoint(OffsetGrabPoint gp) {
        gp.removeGrabPoint(gpo);
    }

    /**
     * Set the GrabPoint that is in the middle of being modified, as a
     * result of a mouseDragged event, or other selection process.
     */
    public void setMovingPoint(GrabPoint gp) {
        super.setMovingPoint(gp);
    }

    /**
     * Given a MouseEvent, find a GrabPoint that it is touching, and
     * set the moving point to that GrabPoint.
     *
     * @param e MouseEvent
     * @return GrabPoint that is touched by the MouseEvent, null if
     *         none are.
     */
    public GrabPoint getMovingPoint(MouseEvent e) {

        movingPoint = null;
        GrabPoint[] gb = getGrabPoints();
        int x = e.getX();
        int y = e.getY();

        for (int i = gb.length - 1; i >= 0; i--) {

            if (gb[i] != null && gb[i].distance(x, y) == 0) {

                setMovingPoint(gb[i]);
                // in case the points are on top of each other, the
                // last point in the array will take precidence.
                break;
            }
        }
        return movingPoint;
    }

    protected int lastRenderType = -1;

    /**
     * Check to make sure the grab points are not null. If they are,
     * allocate them, and them assign them to the array.
     */
    public void assertGrabPoints() {
        int rt = getGraphic().getRenderType();
        if (rt != lastRenderType) {
            clearGrabPoints();
            lastRenderType = rt;
        }

        if (gpc == null) {
            gpc = new GrabPoint(-1, -1);
            gPoints[CENTER_POINT_INDEX] = gpc;
        }

        if (gpo == null) {
            gpo = new OffsetGrabPoint(-1, -1);
            gPoints[OFFSET_POINT_INDEX] = gpo;
            gpo.addGrabPoint(gpc);
        }
    }

    protected void clearGrabPoints() {

        gpc = null;
        gpo = null;

        gPoints[CENTER_POINT_INDEX] = gpc;
        gPoints[OFFSET_POINT_INDEX] = gpo;
    }

    /**
     * Set the grab points for the graphic provided, setting them on
     * the extents of the graphic. Called when you want to set the
     * grab points off the location of the graphic.
     */
    public void setGrabPoints(OMGraphic graphic) {
        if (!(graphic instanceof OMText)) {
            return;
        }
        assertGrabPoints();

        OMText text = (OMText) graphic;
        boolean ntr = text.getNeedToRegenerate();
        int renderType = text.getRenderType();

        LatLonPoint llp;
        int latoffset = 0;
        int lonoffset = 0;

        boolean doStraight = true;

        if (ntr == false) {

            if (renderType == OMGraphic.RENDERTYPE_LATLON
                    || renderType == OMGraphic.RENDERTYPE_OFFSET) {

                if (projection != null) {
                    float lon = text.getLon();
                    float lat = text.getLat();

                    llp = new LatLonPoint(lat, lon);
                    java.awt.Point p = projection.forward(llp);
                    if (renderType == OMGraphic.RENDERTYPE_LATLON) {
                        doStraight = false;
                        gpc.set((int) p.getX(), (int) p.getY());
                    } else {
                        latoffset = (int) p.getY();
                        lonoffset = (int) p.getX();
                        gpo.set(lonoffset, latoffset);
                    }
                }
            }

            if (doStraight) {
                gpc.set(lonoffset + text.getX(), latoffset + text.getY());
            }

            if (renderType == OMGraphic.RENDERTYPE_OFFSET) {
                gpo.updateOffsets();
            }

        } else {
            System.out.println("EditableOMText.setGrabPoint: graphic needs to be regenerated");
        }
    }

    /**
     * Take the current location of the GrabPoints, and modify the
     * location parameters of the OMPoint with them. Called when you
     * want the graphic to change according to the grab points.
     */
    public void setGrabPoints() {

        int renderType = text.getRenderType();
        LatLonPoint llp1;

        Debug.message("eomt", "EditableOMText.setGrabPoints()");

        // Do center point for lat/lon or offset points
        if (renderType == OMGraphic.RENDERTYPE_LATLON) {

            if (projection != null) {
                // movingPoint == gpc
                llp1 = projection.inverse(gpc.getX(), gpc.getY());
                text.setLat(llp1.getLatitude());
                text.setLon(llp1.getLongitude());
                // text.setNeedToRegenerate set
            }
        }

        boolean settingOffset = getStateMachine().getState() instanceof GraphicSetOffsetState
                && movingPoint == gpo;

        // If the center point is moving, the offset distance changes
        if (renderType == OMGraphic.RENDERTYPE_OFFSET) {

            llp1 = projection.inverse(gpo.getX(), gpo.getY());

            text.setLat(llp1.getLatitude());
            text.setLon(llp1.getLongitude());

            if (settingOffset || movingPoint == gpc) {
                // Don't call point.setLocation because we only want
                // to
                // setNeedToRegenerate if !settingOffset.
                text.setX(gpc.getX() - gpo.getX());
                text.setY(gpc.getY() - gpo.getY());
            }

            if (!settingOffset) {
                text.setX(gpc.getX() - gpo.getX());
                text.setY(gpc.getY() - gpo.getY());
            }

            // Set Location has reset the rendertype, but provides
            // the convenience of setting the max and min values
            // for us.
            text.setRenderType(OMGraphic.RENDERTYPE_OFFSET);
        }

        // Do the point height and width for XY and OFFSET render
        // types.
        if (renderType == OMGraphic.RENDERTYPE_XY) {

            if (movingPoint == gpc) {
                text.setX(gpc.getX());
                text.setY(gpc.getY());
            }
        }

        if (projection != null) {
            regenerate(projection);
        }

    }

    /**
     * Get whether a graphic can be manipulated by its edges, rather
     * than just by its grab points.
     */
    public boolean getCanGrabGraphic() {
        return false;
    }

    /**
     * Called to set the OffsetGrabPoint to the current mouse
     * location, and update the OffsetGrabPoint with all the other
     * GrabPoint locations, so everything can shift smoothly. Should
     * also set the OffsetGrabPoint to the movingPoint. Should be
     * called only once at the beginning of the general movement, in
     * order to set the movingPoint. After that, redraw(e) should just
     * be called, and the movingPoint will make the adjustments to the
     * graphic that are needed.
     */
    public void move(java.awt.event.MouseEvent e) {}

    /**
     * Use the current projection to place the graphics on the screen.
     * Has to be called to at least assure the graphics that they are
     * ready for rendering. Called when the graphic position changes.
     *
     * @param proj com.bbn.openmap.proj.Projection
     * @return true
     */
    public boolean generate(Projection proj) {
        if (text != null)
            text.regenerate(proj);
        for (int i = 0; i < gPoints.length; i++) {
            GrabPoint gp = gPoints[i];
            if (gp != null) {
                gp.generate(proj);
            }
        }
        return true;
    }

    /**
     * Given a new projection, the grab points may need to be
     * repositioned off the current position of the graphic. Called
     * when the projection changes.
     */
    public void regenerate(Projection proj) {
        if (text != null)
            text.regenerate(proj);

        setGrabPoints(text);
        generate(proj);
    }

    /**
     * Draw the EditableOMtext parts into the java.awt.Graphics
     * object. The grab points are only rendered if the point machine
     * state is TextSelectedState.TEXT_SELECTED.
     *
     * @param graphics java.awt.Graphics.
     */
    public void render(java.awt.Graphics graphics) {

        State state = getStateMachine().getState();

        if (!(state instanceof GraphicUndefinedState)) {
            if (text != null) {
                text.setVisible(true);
                text.render(graphics);
                text.setVisible(false);
            } else {
                Debug.message("eomg", "EditableOMText.render: null point.");
            }

            int renderType = text.getRenderType();

            if (state instanceof GraphicSelectedState
                    || state instanceof GraphicEditState) {

                for (int i = 0; i < gPoints.length; i++) {
                    GrabPoint gp = gPoints[i];
                    if (gp != null) {
                        if ((i == OFFSET_POINT_INDEX
                                && renderType == OMGraphic.RENDERTYPE_OFFSET && movingPoint == gpo)
                                ||

                                (state instanceof GraphicSelectedState && ((i != OFFSET_POINT_INDEX && renderType != OMGraphic.RENDERTYPE_OFFSET) || (renderType == OMGraphic.RENDERTYPE_OFFSET)))

                        ) {

                            gp.setVisible(true);
                            gp.render(graphics);
                            gp.setVisible(false);
                        }
                    }
                }
            }
        }
    }

    /**
     * If this EditableOMGraphic has parameters that can be
     * manipulated that are independent of other EditableOMGraphic
     * types, then you can provide the widgets to control those
     * parameters here. By default, returns the GraphicAttributes GUI
     * widgets. If you don't want a GUI to appear when a widget is
     * being created/edited, then don't call this method from the
     * EditableOMGraphic implementation, and return a null Component
     * from getGUI.
     *
     * @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 java.awt.Component getGUI(GraphicAttributes graphicAttributes) {
        Debug.message("eomg", "EditableOMPoly.getGUI");
        if (graphicAttributes != null) {
            Component gaGUI = graphicAttributes.getGUI();
            ((JComponent) gaGUI).add(getTextGUI());
            return gaGUI;
        } else {
            return getTextGUI();
        }
    }

    JComboBox sizesFont;
    JToggleButton boldFont;
    JToggleButton italicFont;

    /** Command for text string adjustments. */
    public final static String TextFieldCommand = "TextField";
    public final static String TextFontCommand = "TextFont";
    public final static String TextRotationCommand = "TextRotation";

    protected java.awt.Component getTextGUI() {
        javax.swing.Box attributeBox = javax.swing.Box.createHorizontalBox();

        attributeBox.setAlignmentX(Component.CENTER_ALIGNMENT);
        attributeBox.setAlignmentY(Component.CENTER_ALIGNMENT);

        String textString = "Text";
        if (text != null) {
            textString = text.getData();
        }

        JTextField textField = new JTextField(textString, 25);
        textField.setActionCommand(TextFieldCommand);
        textField.addActionListener(this);
        textField.setMargin(new Insets(0, 1, 0, 1));
        textField.setMinimumSize(new java.awt.Dimension(100, 20));
        textField.setPreferredSize(new java.awt.Dimension(100, 20));
        attributeBox.add(textField);

        // JPanel palette =
        // PaletteHelper.createHorizontalPanel("Rotation");
        javax.swing.Box palette = javax.swing.Box.createHorizontalBox();
        textField = new JTextField(Integer.toString((int) (text.getRotationAngle() * 180 / Math.PI)), 5);
        textField.setActionCommand(TextRotationCommand);
        textField.setToolTipText(i18n.get(EditableOMText.class,
                "textField",
                I18n.TOOLTIP,
                "Text rotation in degrees"));
        textField.setMargin(new Insets(0, 1, 0, 1));
        textField.addActionListener(this);
        textField.setMinimumSize(new java.awt.Dimension(30, 20));
        textField.setPreferredSize(new java.awt.Dimension(30, 20));
        palette.add(textField);
        palette.add(new JLabel("\u00b0 "));
        attributeBox.add(palette);

        String[] sizesStrings = { "3", "5", "8", "10", "12", "14", "18", "20",
                "24", "36", "48" };
        sizesFont = new JComboBox(sizesStrings);
        sizesFont.setToolTipText(i18n.get(EditableOMText.class,
                "sizesFont",
                I18n.TOOLTIP,
                "Font Size"));
        sizesFont.setSelectedItem("" + (text.getFont()).getSize());
        sizesFont.setActionCommand(TextFontCommand);
        sizesFont.addActionListener(this);

        int textButtonWidth = 10;
        int textButtonHeight = 15;

        boldFont = new JToggleButton();
        boldFont.setIcon(getTextAccentToggleButtonImage(textButtonWidth,
                textButtonHeight,
                new Font(boldFont.getFont().getName(), Font.BOLD, boldFont.getFont()
                        .getSize()),
                "B"));

        // Too wide margins for 1 letter look unnatural
        Insets insets = boldFont.getInsets();
        insets.left = insets.left / 2;
        insets.right = insets.right / 2;
        boldFont.setMargin(insets);
        boldFont.setSelected(text.getFont().isBold());
        boldFont.setToolTipText(i18n.get(EditableOMText.class,
                "boldFont",
                I18n.TOOLTIP,
                "Bold Font"));
        boldFont.setActionCommand(TextFontCommand);
        boldFont.addActionListener(this);

        italicFont = new JToggleButton();
        italicFont.setIcon(getTextAccentToggleButtonImage(textButtonWidth,
                textButtonHeight,
                new Font(italicFont.getFont().getName(), Font.ITALIC, italicFont.getFont()
                        .getSize()),
                "I"));
        italicFont.setMargin(insets);
        italicFont.setSelected(text.getFont().isItalic());
        italicFont.setToolTipText(i18n.get(EditableOMText.class,
                "italicFont",
                I18n.TOOLTIP,
                "Italic Font"));
        italicFont.setActionCommand(TextFontCommand);
        italicFont.addActionListener(this);

        attributeBox.add(sizesFont);
        attributeBox.add(boldFont);
        attributeBox.add(italicFont);

        return attributeBox;
    }

    private ImageIcon getTextAccentToggleButtonImage(int width, int height,
                                                     Font f, String s) {
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bi.getGraphics();
        g.setFont(f);
        g.setColor(Color.black);
        FontMetrics fm = g.getFontMetrics();

        int stringWidth = fm.stringWidth(s);
        int stringHeight = f.getSize() - 2;
        g.drawString(s, (width - stringWidth) / 2, height - (height - stringHeight) / 2);
        return new ImageIcon(bi);
    }

    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        String command = e.getActionCommand();

        if (command == TextFontCommand) {
            String FontString = OMText.fontToXFont(text.getFont());
            FontString = FontString.substring(0, FontString.indexOf("-", 3));
            StringBuffer ret = new StringBuffer(FontString);
            if (boldFont.isSelected())
                ret.append("-bold");
            else
                ret.append("-normal");
            if (italicFont.isSelected())
                ret.append("-i");
            else
                ret.append("-o");
            ret.append("-normal");
            ret.append("--" + sizesFont.getSelectedItem());
            ret.append("-*-*-*-*-*-*");
            ret.toString();
            text.setFont(OMText.rebuildFont(ret.toString()));
            repaint();
        } else if (command == TextFieldCommand) {
            text.setData(((JTextField) source).getText());
            text.regenerate(projection);
            repaint();
        } else if (command == TextRotationCommand) {
            Integer rotation = new Integer(((JTextField) source).getText());
            text.setRotationAngle(Math.PI / 180 * (rotation.intValue() % 360));
            text.regenerate(projection);
            repaint();
        }
    }
}
TOP

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

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.