Create new instance of an object in runtime

Is it possible to create and/or delete an instance of a component in the run time?

Let me back up… I want the user to be able to customize the components that are populated on a particular window. Through the use of some input method the user will specify which component to add, the location on the screen, and any parameters that will be passed to that particular component (the value to display, for example). I was hoping, through scripting or some other means, to be able to create a new instance of the component that the user configured and add it to the window. Removing or deleting the instance would also be required.

Otherwise I believe that I will need to have several unused and hidden components that I enable and make visible when the user adds that component to the screen. But as I understand this method eats up the system resources as the hidden components are still executed. Are disabled components executed?

Thanks.

Yes, disabled/hidden components’ bindings are still executed.

There currently isn’t a great way to do this - no way to create components at runtime.

I have some plans to add a “Template Canvas” component in 7.7 which would allow for the arbitrary creation and placement of template instances though, which would allow you to create a screen like you described.

This sort of scripting isn’t generally supported by Inductive Automation but you can still do it. It requires diligence and knowing that it may require maintenance in the future to keep it working. Because it is possible that your code could break in future versions of Ignition.

Here is an example of a script that creates a new label and places it on a window. This code can be put in an event script:

from com.inductiveautomation.factorypmi.application.components import PMILabel
label = PMILabel()
label.text = "My Text"
label.visible = True
root = system.gui.getParentWindow(event).rootContainer
root.addComponent(label)
system.gui.moveComponent(label, 100,100)

You can use the Python class property to find out what class to use to instantiate a new component. For example: print label.class

You can use the dir() function to find available methods on components and objects.

You can use Java’s reflection API to learn more about Vision components and objects: docs.oracle.com/javase/tutorial/reflect/

And use Java and Swing documentation to learn what you need to know about those.

Using what you learn you can create and configure components dynamically in the client runtime through Python scripting. So much fun.

nmudge - this is awesome! exactly what I was hoping for.

I am new to java programming so I appreciate the pointers to the resources.

If I already have a component defined in my project is there a way to create another instance of that particular component?

I tried to do this using the following:

root = event.source.parent
cont = root.getComponent("Container")
root.addComponent(cont)

This seems to create a new component “Container 1” but removes the original component “Container”.

Are you essentially asking if there is a way to copy an existing container with everything in it?

For example let’s say you have a container that is configured a certain way and several components in that container that are configured a certain way and you want to copy that container creating a new container that is configured the same as the original container and contains copies of the components that the original container had? Is this what you are asking?

Well there may be several ways to achieve this sort of thing. I’m not sure if there is any existing function that does the work directly for you or not. You might have to write the code to do the work yourself.

One implementation I think of is creating a new container with the container class, then getting all the components in the original container with container.getComponents() and using the class of each component to create new component instances and perhaps using BeanUtils.copyProperties to copy the configuration of each component to each new component.

You could probably write a Python function that does this work in a generic way.

This thread is making me very nervous.

You guy are treading in very dangerous waters. I need to re-iterate that what you’re doing is not supported, please don’t call into our support lines asking questions about this.

2 Likes

Is perfect.
Is it possible to add an event a button and remove components?
After this is created I can click to call a function.
Ex:
button = PMIButton()
button.actionPerformed(func())
It is just an example to show what I need.
About remove component. When I close and open the window again the component always stay there.
If I want to change component I can’t. Overload.
Please help me.

Please go back a few comments and read what Carl wrote.
The supported way to add and remove components at runtime is by using a Template Canvas. Not by using Ignition's Swing objects directly. There be dragons.

2 Likes

Ok I will see about it, but Is it possible to close a window without committing any changes and/or remove components?
How can I see the system.gui.getParentWindow(event) class.
If it has a method addComponent i think it has something like removeComponent.
Sorry, I new in ignition.

You cannot add your own components to windows programmatically without performing a number of undocumented and unsupported operations on the window and component.