Leo:Could you screen shot what this code actually produces as far as an interface that the user would see?
Searching help on Java Add-ins has left me completely in the dark on what this code would end up looking like or how it launches or anything.
Is the Java IDE environment text based only for defining the form or does it have visual drag and drop tools? I need the real basics to get oriented to decide if I want to even attempt to go down this path.
How is building a Java add-in any different from building a .Net add-in?
In .NET maybe it is hard to capture every possible user "oops".In Java, it's straight-forward.DecimalFormat.. DateFormat.. fun stuff.If you enter junk into this text field, it will default to 0.00 // Create an instance of DecimalFormat to limit the number of integers the user can type into certain fields. DecimalFormat temperatureFormat = new DecimalFormat("##0.00"); ftfTemperature = new JFormattedTextField(new DefaultFormatterFactory(new NumberFormatter(temperatureFormat),new NumberFormatter(temperatureFormat),new NumberFormatter(temperatureFormat))); ftfTemperature.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { ftfTemperature.selectAll(); } }); } }); ftfTemperature.setBounds(120, 8, 85, 20); panel.add(ftfTemperature);
// Create an instance of DecimalFormat to limit the number of integers the user can type into certain fields. DecimalFormat temperatureFormat = new DecimalFormat("##0.00"); ftfTemperature = new JFormattedTextField(new DefaultFormatterFactory(new NumberFormatter(temperatureFormat),new NumberFormatter(temperatureFormat),new NumberFormatter(temperatureFormat))); ftfTemperature.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { ftfTemperature.selectAll(); } }); } }); ftfTemperature.setBounds(120, 8, 85, 20); panel.add(ftfTemperature);
Doesn't python have an OS module that you can call?os.system(your application, your parameter)
from subprocess import check_call check_call(["DesktopConsoleApplication1.exe", "Collision_Segment_Diagram2.mxd"])
using System; using System.Collections.Generic; using System.Text; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Framework; namespace DesktopConsoleApplication1 { class Program { private static LicenseInitializer m_AOLicenseInitializer = new DesktopConsoleApplication1.LicenseInitializer(); [STAThread()] static void Main(string[] args) { //ESRI License Initializer generated code. m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeArcView, esriLicenseProductCode.esriLicenseProductCodeArcEditor, esriLicenseProductCode.esriLicenseProductCodeArcInfo }, new esriLicenseExtensionCode[] { }); //ESRI License Initializer generated code. try { IAppROT aprot = new AppROT(); IApplication application = null; for(int a = 0; a < aprot.Count; a++) { application = aprot.get_Item(a); System.Console.WriteLine("Application Title = " + application.Document.Title); foreach (string curItem in args) { System.Console.WriteLine("Args: " + curItem); if (application.Document.Title == curItem) { System.Console.WriteLine("The map was found! Do something!"); } else { System.Console.WriteLine("The open map does not match that title."); } } } if (aprot.Count == 0) { System.Console.WriteLine("No ArcMap application is open"); } //System.Console.ReadLine(); //Uncomment this line if you want to have the console pause before closing. } catch (Exception e) { Console.WriteLine("{0} Exception caught.", e); } //Do not make any call to ArcObjects after ShutDownApplication() m_AOLicenseInitializer.ShutdownApplication(); } } }
This prints the title of the only mxd open on my machine, index = 0. You would probably have to make sure you have the right mxd application name by iterating over the count of open mxds and getting the title. public class Console { public static void main(String[] args) { EngineInitializer.initializeEngine(); initializeArcGISLicenses(); try { IAppROT aprot = new AppROT(); IApplication application = aprot.getItem(0); System.out.println(application.getDocument().getTitle()); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } static void initializeArcGISLicenses() { try { com.esri.arcgis.system.AoInitialize ao = new com.esri.arcgis.system.AoInitialize(); if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView); } catch (Exception e) { e.printStackTrace(); } } }
public class Console { public static void main(String[] args) { EngineInitializer.initializeEngine(); initializeArcGISLicenses(); try { IAppROT aprot = new AppROT(); IApplication application = aprot.getItem(0); System.out.println(application.getDocument().getTitle()); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } static void initializeArcGISLicenses() { try { com.esri.arcgis.system.AoInitialize ao = new com.esri.arcgis.system.AoInitialize(); if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView); } catch (Exception e) { e.printStackTrace(); } } }
Lines of Python code to restrict a script tool field to a long: Define the input as a Long.Lines of Python code to restrict a script tool field to a date: Define the input as a Date.Hard to get any simpler than that.
What if you wrote a console ArcObjects application that you execute from python? I believe you can get a list of current ArcMap application references from the IAppROT interface. That might work.
Can I interest you in writing a Java add-in? 😄
At first thought, your pattern sounds like the observer pattern, notify registered observers when an event occurs, except you're using two different languages, so I'm not sure how you would connect the two.At second thought, there is: com.esri.arcgis.carto.IActiveViewEventsFocusMapChangedEvent Which might work.Lastly, Add-ins respond to user initiated events, so I'm not sure how you would initiate the tool, button, menu, utility object or extension that should be listening for the events from python.
My python script tool is unconventional and is not merely designed to act as a geoprocessing tool. It acts like a form object with user interface capabilities. I do not want the user to simply feed parameters to the tool. I intend for them to interact with the tool. I am aware that with .Net I could design a form using ArcObjects, but I have no interest in doing that.
I want to know if it is possible to create an Add-in extension that listens for map refresh events to specifically respond to the actions of a python script?I envision adding a hidden text object into a specific kind of map that will at first indicate to the Add-in Extension that nothing needs to be done. When the Python script runs it will write to that text object to set a flag telling the Extension that it is processing a change to the map, so ignore any map refresh actions during the script processing. Just prior to completion of the Python script, the Python script will update the Text Object to say that it just finished and needs the Extension to do its thing. Then the Python script will refresh the map. I assume the Add-in Extension can detect the map refresh event triggered by the Python script, read the text object to detect that python wants the extension to run and then the extension can fire its action on the map. When the extension finishes it will reset the text object back to the state indicating that nothing needs to be done by the extension.Does this sound like it will work?I want the Add-in to detect when arcpy.mapping finishes updating everything that it can in the map, and then have the extension change the data frame clipping geometry to match a feature's shape according to the current definition query on a layer that the python script set. I do not want the user to have to push another button after the Python script finishes to do things that Python seemingly cannot do, and I do not want the Add-in to do the Python script actions. I do not see any other way to have Python trigger an ArcObjects action within the currently open map, since the ctypes functionality says it is limited to basic C++ types and I do not see a way to pass a hook for the current map to an ArcObjects DLL method from Python.Please correct me if I am wrong about any of this or if there is a better approach to do what I want.
What about that: embed your Python script into a Python script tool inside a custom toolbox. Extent your add-in with a button. If the user clicks the button, the add-in runs the script tool (synchron) and after it finished, it does the other stuff with ArcObjects. For deployment (to the assembly cache) you can add the custom toolbox as a resource to the add-in. The code for using an embedded toolbox is something like that:// Initialize the geoprocessor. IGeoProcessor2 gp = new GeoProcessorClass();// Add the toolbox.string strPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);string strToolbox = strPath + "\\PythonTools.tbx";gp.AddToolbox(strToolbox);// Generate the array of parameters.IVariantArray parameters = new VarArrayClass();parameters.Add(inString);// Execute the model tool by name.IGeoProcessorResult result = gp.Execute("Reply", parameters, null);// Ergebnis zurückliefernstring reply = result.GetOutput(0).GetAsText();
Přihlášení členové mohou přispívat, sledovat aktualizace a další. Jste tu noví? Zaregistrujte si bezplatný účet.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.