Quantcast
Channel: Forums - ArcObjects SDKs
Viewing all articles
Browse latest Browse all 1374

HOW TO: Implement Model View Controller in an ArcMap Tool Add-in - Java

$
0
0
This sample was intended to show how to implement the MVC pattern in an ArcMap add-in.

If you like it, ok. If not, ok. Feel free to comment or nitpick it.

Code:

package com.domain.somename;

import java.awt.event.MouseEvent;
import java.io.IOException;

import com.esri.arcgis.addins.desktop.Tool;
import com.esri.arcgis.arcmap.Application;
import com.esri.arcgis.arcmapui.IMxDocument;
import com.esri.arcgis.carto.Map;
import com.esri.arcgis.framework.IApplication;
import com.esri.arcgis.interop.AutomationException;

public class Tool1 extends Tool {

    /**
    * Called when the tool is activated by clicking it.
    */
    @Override
    public void activate() throws IOException, AutomationException {
        // Not doing anything in here...
    }

    /**
    * Initializes this button with the ArcGIS application.
    */
    @Override
    public void init(IApplication app) throws IOException, AutomationException {
        super.init(app);
       
        try {
            mxDocument = (IMxDocument)app.getDocument();
           
            try {
                left = ((Application) app).getLeft() + 100;
                top = ((Application) app).getTop() + 200;
            } catch (IOException e2) {
                e2.printStackTrace();
            }
           
        } catch (AutomationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
    * Called when a mouse button is pressed while the tool is active.
    */
    @Override
    public void mousePressed(MouseEvent mouseEvent) {
        super.mousePressed(mouseEvent);
       
        // get an instance of our view
        if(t1View == null){
            t1View = Tool1View.getInstance();
            t1View.addWindowListener(t1View);
        }
       
        // create an instance of the model
        if(t1Model == null){
            t1Model = new Tool1Model(t1View, mouseEvent);
            t1Model.setMxDoc(mxDocument);
        }
       
        // create an instance of the controller
        if(t1Controller == null){
            try {
                t1Controller = new Tool1Controller(t1View, t1Model, (Map)mxDocument.getActiveView().getFocusMap());
            } catch (AutomationException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       
        // display the View
        t1View.setBounds(left, top, 270, 170);
        t1View.toFront();
        t1View.setVisible(true);
       
    }
   
    public IApplication getApp() {
        return app;
    }

    public IMxDocument getMxDocument() {
        return mxDocument;
    }
   
    private IApplication app;
    private IMxDocument mxDocument;
   
    private Tool1View t1View = null;
    private Tool1Model t1Model = null;
    private Tool1Controller t1Controller = null;
   
    private int left;
    private int top;

}

Code:

package com.domain.somename;

import java.awt.event.MouseEvent;
import java.io.IOException;

import javax.swing.JOptionPane;

import com.esri.arcgis.arcmapui.IMxDocument;
import com.esri.arcgis.interop.AutomationException;

public class Tool1Model {

    public Tool1Model(Tool1View view, MouseEvent me){
        m_tool1View = view;
        m_me = me;
    }
   
    public void handleSubmit(){
        int xcoord = m_me.getX();
        int ycoord = m_me.getY();
       
        String message = m_tool1View.getTxtDescription().getText() + " was placed at screen coordinates: " + xcoord + "," + ycoord;
       
        JOptionPane.showMessageDialog(m_tool1View, message);
        JOptionPane.showMessageDialog(m_tool1View, "... But not really, this was just a lame example...");
       
        try {
            mxDoc.getActiveView().refresh();
        } catch (AutomationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
    /**
    * @return the mxDoc
    */
    public IMxDocument getMxDoc() {
        return mxDoc;
    }

    /**
    * @param mxDoc the mxDoc to set
    */
    public void setMxDoc(IMxDocument mxDoc) {
        this.mxDoc = mxDoc;
    }

    private Tool1View m_tool1View = null;
    private MouseEvent m_me;
   
    private IMxDocument mxDoc;
}

Code:

package com.domain.somename;

import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.border.TitledBorder;
import javax.swing.JTextField;
import javax.swing.JButton;

public class Tool1View extends JFrame implements WindowListener{

    private static final long serialVersionUID = -697599487543207794L;
    private static Tool1View instance = null;
    private JPanel contentPane;
    private JTextField txtDescription;
    private JButton btnSubmit;

    /**
    * Make our view a singleton because there is no reason to have multiple instances of this view
    */
    public static Tool1View getInstance(){
        if(instance == null){
            instance = new Tool1View();
        }
        return instance;
    }
   
    public Tool1View() {
        constructGUI();
    }
   
    /**
    * Construct the GUI for Tool1View
    */
    private void constructGUI(){
       
        setTitle("Tool1 GUI");
        contentPane = new JPanel();
        setContentPane(contentPane);
        contentPane.setLayout(null);
       
        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(null, "Enter a description for this location", TitledBorder.LEADING, TitledBorder.TOP, null, null));
        panel.setBounds(10, 11, 234, 79);
        contentPane.add(panel);
        panel.setLayout(null);
       
        JLabel label = new JLabel("Description:");
        label.setBounds(10, 35, 70, 14);
        panel.add(label);
       
        txtDescription = new JTextField();
        txtDescription.setColumns(10);
        txtDescription.setBounds(90, 32, 125, 20);
        panel.add(txtDescription);
       
        btnSubmit = new JButton("Submit");
        btnSubmit.setBounds(155, 96, 89, 23);
        contentPane.add(btnSubmit);
    }

    public JTextField getTxtDescription() {
        return txtDescription;
    }

    public JButton getBtnSubmit() {
        return btnSubmit;
    }
   
    /**
    * Assign an ActionListener to this button from the Tool1Controller.
    */
    void addSubmitListener(ActionListener sal){
        btnSubmit.addActionListener(sal);
    }
   
    /**
    * Override the windowClosing event.
    */
    @Override
    public void windowClosing(WindowEvent e) {
        instance.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }
    @Override
    public void windowOpened(WindowEvent e) {
    }
    @Override
    public void windowClosed(WindowEvent e) {
    }
    @Override
    public void windowIconified(WindowEvent e) {
    }
    @Override
    public void windowDeiconified(WindowEvent e) {
    }
    @Override
    public void windowActivated(WindowEvent e) {
    }
    @Override
    public void windowDeactivated(WindowEvent e) {
    }
}

Code:

package com.domain.somename;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import com.esri.arcgis.carto.Map;
import com.esri.arcgis.interop.AutomationException;

public class Tool1Controller {

    public Tool1Controller(Tool1View view, Tool1Model model, Map map){
        c_tool1View = view;
        c_tool1Model = model;
        c_map = map;
       
        c_tool1View.addSubmitListener(new AddSubmitListener());
    }
   
    /**
    * Inner class used as the ActionListener for the btnSubmit in Tool1View.
    */
    private class AddSubmitListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            // call the model to handle the button event...
            c_tool1Model.handleSubmit();
           
            // you can let the controller handle map refresh, rather than in the model...
            try {
                c_map.refresh();
            } catch (AutomationException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }

    }
   
    private Tool1View c_tool1View;
    private Tool1Model c_tool1Model;
    private Map c_map;
}


Viewing all articles
Browse latest Browse all 1374

Trending Articles