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.
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;
}