arcgissamples\cartography\SplineTextMain.java—ArcObjects 10.4 Help for Java | ArcGIS for Desktop
Spline text
arcgissamples\cartography\SplineTextMain.java
/* Copyright 2015 ESRI
* 
* All rights reserved under the copyright laws of the United States
* and applicable international laws, treaties, and conventions.
* 
* You may freely redistribute and use this sample code, with or
* without modification, provided you include the original copyright
* notice and use restrictions.
* 
* See the use restrictions at <your ArcGIS install location>/DeveloperKit10.4/userestrictions.txt.
* 
*/
package arcgissamples.cartography;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;

import com.esri.arcgis.beans.map.MapBean;
import com.esri.arcgis.carto.LineElement;
import com.esri.arcgis.carto.TextElement;
import com.esri.arcgis.carto.esriViewDrawPhase;
import com.esri.arcgis.controls.IMapControlEvents2Adapter;
import com.esri.arcgis.controls.IMapControlEvents2OnDoubleClickEvent;
import com.esri.arcgis.controls.IMapControlEvents2OnKeyDownEvent;
import com.esri.arcgis.controls.IMapControlEvents2OnKeyUpEvent;
import com.esri.arcgis.controls.IMapControlEvents2OnMouseDownEvent;
import com.esri.arcgis.controls.IMapControlEvents2OnMouseMoveEvent;
import com.esri.arcgis.display.INewBezierCurveFeedback;
import com.esri.arcgis.display.IScreenDisplay;
import com.esri.arcgis.display.ISymbol;
import com.esri.arcgis.display.NewBezierCurveFeedback;
import com.esri.arcgis.display.RgbColor;
import com.esri.arcgis.display.SimpleLineSymbol;
import com.esri.arcgis.display.SimpleTextPath;
import com.esri.arcgis.display.TextSymbol;
import com.esri.arcgis.display.esriScreenCache;
import com.esri.arcgis.display.esriSimpleLineStyle;
import com.esri.arcgis.display.esriTextHorizontalAlignment;
import com.esri.arcgis.display.esriTextVerticalAlignment;
import com.esri.arcgis.geometry.ICurve;
import com.esri.arcgis.geometry.IPoint;
import com.esri.arcgis.geometry.IPolyline;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;
import com.esri.arcgis.interop.AutomationException;

/**
 * This sample demonstrates a way to draw a spline text along bezier curve.
 */
public class SplineTextMain extends JFrame {

  private static final long serialVersionUID = 1L;
  static AoInitialize aoInit;
  boolean tracking = false;
  MapBean mapBean = new MapBean();
  JLabel textLabel = new JLabel();
  SimpleTextPath textPath;
  TextSymbol textSymbol;
  ICurve curve;
  boolean typing;
  INewBezierCurveFeedback newBzCurveFeedback; // Feedback object to track a bezier curve

  public SplineTextMain() {
    initUI();
  }

  public static void main(String s[]) {
    try {
      EngineInitializer.initializeVisualBeans();
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      initializeArcGISLicenses();
      new SplineTextMain();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  
  static void initializeArcGISLicenses() {
    try {
      aoInit = new AoInitialize();
      
      if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeBasic) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeBasic);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Lay out the User Interface, and set up event listeners
   */
  private void initUI() {
    this.setTitle("Spline Text Sample Application");
    this.setSize(new Dimension(600, 500));
    this.getContentPane().setLayout(new BorderLayout());
    this.textLabel.setText("Draw spline, doulble click, type letters, hit Enter.");
    this.getContentPane().add(this.mapBean, BorderLayout.CENTER);
    this.getContentPane().add(this.textLabel, BorderLayout.SOUTH);
    this.setVisible(true);

    // set listeners
    try {
      this.mapBean.addIMapControlEvents2Listener( new IMapControlEvents2Adapter() {
        private static final long serialVersionUID = 1L;
        public void onMouseDown(IMapControlEvents2OnMouseDownEvent event) throws IOException, AutomationException {
          supportMouseDown(event);
        }
        public void onDoubleClick(IMapControlEvents2OnDoubleClickEvent event) throws IOException, AutomationException {
          supportDoubleClick();
        }
        public void onMouseMove(IMapControlEvents2OnMouseMoveEvent event) throws IOException, AutomationException {
          supportMouseMove(event);
        }
        public void onKeyDown(IMapControlEvents2OnKeyDownEvent event) throws IOException, AutomationException {
          supportKeyDown(event);
        }
        public void onKeyUp(IMapControlEvents2OnKeyUpEvent event) throws IOException, AutomationException {
          supportKeyUp(event);
        }
      });
    } catch( IOException e) {
      e.printStackTrace(); // never happened
    }
    this.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        try {
          aoInit.shutdown();
        } catch(IOException ex) {
          // exit anyway
        }
        System.exit(0);
      }
    });
  }

  /**
   * Support mouse events for mapBean
   */
  protected void supportMouseDown(IMapControlEvents2OnMouseDownEvent event) throws IOException, AutomationException {
    this.tracking = true;
    IPoint pnt = this.mapBean.getActiveView().getScreenDisplay().getDisplayTransformation().toMapPoint(event.getX(), event.getY());
    if( this.newBzCurveFeedback == null ) {
      // Create a symbol (and color) for the feedback, and set the start point.
      this.newBzCurveFeedback = new NewBezierCurveFeedback();
      this.newBzCurveFeedback.setDisplayByRef( this.mapBean.getActiveView().getScreenDisplay() );
      this.newBzCurveFeedback.start(pnt);
    } else {
      // Otherwise use the current mouse location to add a vertex to the current feedback.
      this.newBzCurveFeedback.addPoint(pnt);
    }
  }

  /**
   * Support mouse events for mapBean
   */
  public void supportDoubleClick() throws IOException, AutomationException {
    this.tracking = false;
    // Get the geometry (Line) returned from the feedback
    IPolyline geomLn = this.newBzCurveFeedback.stop();
    this.newBzCurveFeedback = null;
    // If it is valid then create a LineElement on the ActiveView using the 'AddCreateElement' procedure
    if( geomLn != null ) {
      // Create the TextPath and set it's geometry with the new curve.
      this.curve = geomLn;
      this.textPath = new SimpleTextPath();
      this.textPath.setGeometryByRef(this.curve);
      // Create a Line so we can see where the text will go.
      addCreateElement();
      this.mapBean.getActiveView().partialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
      // User should now enter text.
      setupSymbol();
      drawCurrentText();
      this.textSymbol.setText("");
      this.typing = true;
    }
  }

  /**
   * Support mouse events for mapBean
   */
  protected void supportMouseMove(IMapControlEvents2OnMouseMoveEvent event) throws IOException, AutomationException {
    // Check if the user is currently using the feedback.
    IPoint pnt = this.mapBean.getActiveView().getScreenDisplay().getDisplayTransformation().toMapPoint(event.getX(), event.getY());
    if(this.tracking){
      this.newBzCurveFeedback.moveTo(pnt);
    }
  }

  /**
   * Support mouse events for mapBean
   */
  public void supportKeyDown(IMapControlEvents2OnKeyDownEvent event) throws IOException, AutomationException {
    // If we are in typing mode (i.e. have finished tracking the Line), check for the user pressing return.
    int keyCode = event.getKeyCode();
    if( (keyCode == 13 || keyCode == 27) && this.typing ) { // 12 - return, 27 - escape
      // Now finish the Text, and add a TextElement to the view to make the text persistent.
      makePath();
      this.typing = false;
    }
  }

  /**
   * Support mouse events for mapBean
   */
  public void supportKeyUp(IMapControlEvents2OnKeyUpEvent event) throws IOException, AutomationException {
    // Add each character to the end of the Text string.
    int keyCode = event.getKeyCode();
    if (keyCode == 16) { // shift key
      return;
    }
    int shiftCode = event.getShift();
    if (keyCode >= 65 && keyCode <= 90) {
      if (shiftCode == 0) {
        keyCode += 32;
      }
    }
    if( this.typing ) {
      this.textSymbol.setText(this.textSymbol.getText() + String.valueOf((char)keyCode) );
      // Draw the current symbol to the active view.
      drawCurrentText();
    }
  }

  /**
   * This routine creates a Line element.
   * We use the IElement interface to set the LineElement's Geometry.
   */
  private void addCreateElement() throws IOException, AutomationException {
    // create line element
    LineElement elem = new LineElement();
    elem.setGeometry(this.curve);
    RgbColor rgb = new RgbColor();
    rgb.setRed(255);
    rgb.setGreen(0);
    rgb.setBlue(255);
    SimpleLineSymbol simpleLnSym = new SimpleLineSymbol();
    simpleLnSym.setColor(rgb);
    simpleLnSym.setStyle(esriSimpleLineStyle.esriSLSSolid);
    elem.setSymbol(simpleLnSym);
    // add element in the map
    this.mapBean.getActiveView().getGraphicsContainer().addElement(elem, 0);
  }

  /**
   * Set up a TextSymbol for drawing the text.
   */
  private void setupSymbol() throws IOException, AutomationException {
    RgbColor color = new RgbColor();
    color.setRGB(0);
    this.textSymbol = new TextSymbol();
    this.textSymbol.setColor(color);
    this.textSymbol.setHorizontalAlignment(esriTextHorizontalAlignment.esriTHALeft);
    this.textSymbol.setVerticalAlignment(esriTextVerticalAlignment.esriTVABaseline);
    this.textSymbol.setClip(false);
    this.textSymbol.setSize(20);

    // Set it's TextPath to be the TextPath we created. Now text will be splined along this line.
    this.textSymbol.setTextPathByRef(this.textPath);
    this.textSymbol.setText("Text");
    this.textSymbol.setXOffset(0);
    this.textSymbol.setYOffset(0);
  }

  /**
   * Draw the current text to the display.
   */
  private void drawCurrentText() throws IOException, AutomationException {
    IScreenDisplay screenDisplay = this.mapBean.getActiveView().getScreenDisplay();
    screenDisplay.startDrawing(0, (short)esriScreenCache.esriNoScreenCache);
    ISymbol symbol = this.textSymbol;
    screenDisplay.setSymbol(symbol);
    screenDisplay.drawText( this.curve, this.textSymbol.getText() );
    screenDisplay.finishDrawing();
  }

  /**
   * Create a graphic element to persist our new text.
   */
  private void makePath() throws IOException, AutomationException {
    TextElement textElement = new TextElement();
    textElement.setScaleText(false);
    textElement.setSymbol(this.textSymbol);
    textElement.setText(this.textSymbol.getText());
    // Set the element's Geometry.
    textElement.setGeometry(this.curve);
    // If we're using a Line or Bezier curve, we add a graphic to the view to show the line
    this.mapBean.getActiveView().getGraphicsContainer().addElement(textElement, 0);
    this.mapBean.getActiveView().partialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
  }

}