Editing tools

Download Sample Viewer

Description

This application shows the functionality of the toolkit's JEditTools and JTemplatePicker and how to use them together to create a rich editing environment. Features of the chosen template can be added to the map via mouse clicks. An attribute editor can optionally be shown when a feature is added. This sample uses a local geodatabase which has feature class templates defined for editing.

Code snippet


    // add template picker
    JTemplatePicker jPicker = new JTemplatePicker(map);
    jPanel.add(jPicker, BorderLayout.WEST);
    jPicker.setIconWidth(40);
    jPicker.setIconHeight(30);
    jPicker.setShowNames(true);
    jPicker.setWatchMap(true);
    // show an attribute editor when a feature is added
    jPicker.setShowAttributeEditor(true);

    // add edit tools picker
    JEditToolsPicker editToolsPicker = new JEditToolsPicker(map);
    editToolsPicker.setCreationOverlay(jPicker.getOverlay());
    jPanel.add(editToolsPicker, BorderLayout.NORTH);
  

Sample Code

/* Copyright 2014 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.*/
package com.esri.client.samples.editing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

import com.esri.core.geodatabase.Geodatabase;
import com.esri.core.geodatabase.GeodatabaseFeatureTable;
import com.esri.core.geometry.Envelope;
import com.esri.map.ArcGISTiledMapServiceLayer;
import com.esri.map.FeatureLayer;
import com.esri.map.JMap;
import com.esri.map.LayerList;
import com.esri.map.MapEvent;
import com.esri.map.MapEventListenerAdapter;
import com.esri.runtime.ArcGISRuntime;
import com.esri.toolkit.editing.JEditToolsPicker;
import com.esri.toolkit.editing.JTemplatePicker;

/***
 * This application shows the functionality of the toolkit's JEditTools and JTemplatePicker 
 * and how to use them together to create a rich editing environment. Features of the chosen 
 * template can be added to the map via mouse clicks. An attribute editor can optionally be 
 * shown when a feature is added. This sample uses a local geodatabase which has feature 
 * class templates defined for editing.
 */
public class LocalEditTools {

  private JPanel jPanel;
  private JMap map;
  private Geodatabase geodatabase;
  private static String FSP = System.getProperty("file.separator");
  private static final String RELATIVE_PATH = 
      "disconnected" + FSP + "geodatabase" + FSP + "fire.geodatabase";
  private static final String GEODATABASE_PATH = getPathSampleData() + FSP + RELATIVE_PATH;

  /**
   * Constructor
   * @throws FileNotFoundException 
   */
  public LocalEditTools() throws FileNotFoundException {
    initialize();
  }

  public JPanel createUI() {
    return jPanel;
  }

  private void initialize() throws FileNotFoundException {
    
    // create UI
    jPanel = new JPanel();
    jPanel.setLayout(new BorderLayout(2, 0));
    jPanel.setBackground(Color.DARK_GRAY);

    // add map
    map = new JMap();
    jPanel.add(map, BorderLayout.CENTER);
    
    JPanel pickerPanel = new JPanel();
    pickerPanel.setLayout(new BorderLayout());
    pickerPanel.setBackground(Color.DARK_GRAY);
    
    // create template picker 
    final JTemplatePicker jPicker = new JTemplatePicker(map);
    jPicker.setIconWidth(40);
    jPicker.setIconHeight(30);
    jPicker.setShowNames(true);
    jPicker.setWatchMap(true);
    // show an attribute editor when a feature is added
    jPicker.setShowAttributeEditor(true);
    
    // create check box for whether we show an attribute editor when adding features 
    JCheckBox checkBox = new JCheckBox(" Show attribute editor on add");
    checkBox.setBorder(new EmptyBorder(10, 10, 10, 10));
    checkBox.setBackground(Color.DARK_GRAY);
    checkBox.setForeground(Color.WHITE);
    checkBox.setFocusPainted(false);
    checkBox.addItemListener(new ItemListener() {
      
      @Override
      public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.DESELECTED) {
          jPicker.setShowAttributeEditor(false);
        } else if (e.getStateChange() == ItemEvent.SELECTED) {
          jPicker.setShowAttributeEditor(true);
        }
      }
    });
    checkBox.setSelected(true);
    pickerPanel.add(checkBox, BorderLayout.NORTH);
    pickerPanel.add(jPicker, BorderLayout.CENTER);
    jPanel.add(pickerPanel, BorderLayout.WEST);
    
    // add edit tools picker
    JEditToolsPicker editToolsPicker = new JEditToolsPicker(map);
    editToolsPicker.setCreationOverlay(jPicker.getOverlay());
    jPanel.add(editToolsPicker, BorderLayout.NORTH);

    // add a basemap
    LayerList layers = map.getLayers();
    layers.add(new ArcGISTiledMapServiceLayer(
        "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"));

    // add a feature layer from each feature table in our geodatabase
    geodatabase = new Geodatabase(GEODATABASE_PATH);
    List<GeodatabaseFeatureTable> allTables = geodatabase.getGeodatabaseTables();
    for (GeodatabaseFeatureTable t : allTables) {
      FeatureLayer layer = new FeatureLayer(t);
      layers.add(layer);
    }

    // set an initial extent
    Envelope envelope = new Envelope(-13650727, 4541257, -13609876, 4556999);
    map.setExtent(envelope);
    map.addMapEventListener(new MapEventListenerAdapter() {

      @Override
      public void mapReady(MapEvent event) {
        map.zoom(0.5);
      }
    });
  }

  /**
   * Starting point of this application.
   * @param args
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          LocalEditTools templatePickerApp = new LocalEditTools();
          JFrame window = templatePickerApp.createWindow();
          window.add(templatePickerApp.createUI());
          window.setVisible(true);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  /**
   * Creates the application window, disposes the map and geodatabase on 
   * application exit (window closing).
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame();
    window.setBounds(100, 100, 1000, 700);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout(0, 0));
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        if (map!=null) map.dispose();
        if (geodatabase!=null) geodatabase.dispose();
      }
    });
    return window;
  }

  private static String getPathSampleData() {
    String dataPath = null;
    String javaPath = ArcGISRuntime.getInstallDirectory();
    if (javaPath != null) {
      if (!(javaPath.endsWith("/") || javaPath.endsWith("\\"))){
        javaPath += FSP;
      }
      dataPath = javaPath + "sdk" + FSP + "samples" + FSP + "data" + FSP;
    }
    File dataDir = new File(dataPath);
    if (!dataDir.exists()) { 
      dataPath = ".." + FSP + "data" + FSP;
      dataDir = new File(dataPath);
    }

    return copyIfNoCreateFileAccess(dataDir, RELATIVE_PATH);
  }

  /**
   * Copies file to java.io.tmpdir if the user does not have permission to create file
   * in the current dataDir.
   * @param dataDir directory containing the file to be copied.
   * @param relativeFilePath path of file to be copied relative to the dataDir.
   * @return the path of directory that contains the file copied. This will be in the java.io.tmpdir
   * if copied, otherwise it will be same as input dataDir.
   */
  private static String copyIfNoCreateFileAccess(File dataDir, String relativeFilePath) {
    // check if can create a file in the data directory.
    // can't use File.canWrite() because create is considered different from write. 
    File tempFolder = null;
    try {
      tempFolder = new File(dataDir.getAbsolutePath() + FSP + "temp");
      if (tempFolder.exists()) {
        tempFolder.delete();
      }
      tempFolder.mkdir();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    if (tempFolder != null && tempFolder.exists()) {
      tempFolder.delete();
      return dataDir.getAbsolutePath();
    }

    // no permission to create a new file in the existing data folder.
    // so copy the data file to the java.io.tmpdir folder.
    String tempDataDir = System.getProperty("java.io.tmpdir") + FSP + 
        "ArcGIS SDKs" + FSP + "java" + ArcGISRuntime.getAPIVersion() + 
        FSP + "sdk" + FSP + "samples" + FSP + "data"; 

    String fromFilePath = dataDir + FSP + relativeFilePath;
    String toFilePath = tempDataDir + FSP + relativeFilePath;
    FileInputStream in = null;
    FileOutputStream out = null;
    try {
      File toFile = new File(toFilePath);
      if (toFile.exists()) {
        return tempDataDir;
      }
      toFile.getParentFile().mkdirs();
      toFile.createNewFile();
      System.out.println("Copying file from " + fromFilePath + " to " + toFile.getAbsolutePath());
      in = new FileInputStream(fromFilePath);
      out = new FileOutputStream(toFile);
      byte[] byteBuf = new byte[4096]; 
      int numBytesRead;
      while ((numBytesRead = in.read(byteBuf)) != -1) {
        out.write(byteBuf, 0, numBytesRead);
      }
    } catch (Exception ex) {
      JOptionPane.showMessageDialog(null, wrap(ex.getMessage()));
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
      if (out != null) {
        try {
          out.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
    System.out.println("Copy completed.");
    return tempDataDir;
  }
  
  private static String wrap(String str) {
    // create a HTML string that wraps text when longer
    return "<html><p style='width:200px;'>" + str + "</html>";
  }
}
Feedback on this topic?