I’m working on a custom Ignition Vision component that extends AbstractVisionComponent in Ignition 8.0.17, and I'm running into some issues with how properties are displayed in the Designer Property Editor. Specifically, all of my custom properties, as well as inherited ones from AbstractVisionComponent and JComponent, are being lumped into the Misc category, regardless of how I try to organize them in my BeanInfo class.
Current Setup
Here’s an outline of my current setup:
My component class, ControlPanel, extends AbstractVisionComponent.
I’ve created a BeanInfo class (ControlPanelBeanInfo) to define the properties and their categories.
I use addProp() in the BeanInfo class to define properties and specify their categories (e.g., "Data", "Appearance", etc.).
The Problem
Even though I define categories for my properties in the BeanInfo class, when I drop the component onto a Vision window in the Ignition Designer, all the properties show up under the Misc category instead of being organized into the categories I specified (e.g., Data, Appearance, etc.).
Additionally, all the properties that AbstractVisionComponent inherits from JComponent are automatically included in the Misc category. This makes the property list cluttered and difficult to navigate.
What I’ve Tried
Categorizing Properties in BeanInfo:
I’ve used the addProp() method in my BeanInfo class to assign properties to categories like "Data" and "Appearance". Here’s an example of what my code looks like:
addProp("TagPath", "Tag Path", "The tag path for the component", "Data", PREFERRED_MASK | BOUND_MASK);
addProp("NumVal", "Numeric Value", "A numeric value for display", "Data", PREFERRED_MASK | BOUND_MASK);
However, despite this, all properties still show up under Misc in the Designer.
Hiding Unwanted Inherited Properties:
I tried using removeProp() to hide some of the inherited properties that are cluttering the Misc category, but this didn't seem to have any effect either.
Desired Outcome
What I would like to achieve is:
Custom properties grouped under the appropriate categories (e.g., Data, Appearance, Behavior) as defined in the BeanInfo class.
Reduce the number of inherited properties from JComponent that appear in the Property Editor, or at least hide the irrelevant ones.
Ensure that properties added to the component are displayed in a clean, organized way in the Designer.
Questions
How can I ensure that properties show up in the correct categories in the Property Editor?
Is there a way to prevent inherited properties from JComponent from being automatically included under Misc?
Are there any alternative approaches or best practices for handling property organization in Ignition Vision components?
Any help or suggestions would be greatly appreciated!
Sounds like the designer is not even finding your BeanInfo class. Did you add your bean info package name to the search path (as shown in the Vision component example) ?
I am a system integrator working with some old Ignition projects. Customers don't always like to change things with a working system. I wholeheartedly agree that these projects should be upgraded to the most recent version, but the trick for me is convincing them to shell out the money/downtime for it.
It's involved, and a disaster for the poor soul who has to deal with this later. A 3rd party module should not be wiring up the data flow of a project. Just make the functionality possible.
Our goal is to provide control over a specific machine to the user, without letting the user mess with the functionality too much. Instead of directly creating the binding, could I create a tag change listener and populate the value of the property with the new value of the tag? If so, how would I do this? The examples are a little unclear about tag change listeners. This is the preliminary code I have:
private void bindTagToNumVal(String tagPath) throws IOException {
// Parse the tag path correctly
TagPath path = TagPathParser.parse(tagPath);
// Create a listener for tag changes
TagChangeListener listener = event -> {
// When the tag value changes, handle the new value
QualifiedValue newValue = event.getValue();
handleTagChange(newValue); // Call the method to handle the new tag value
};
// Subscribe to tag changes using the tag path and listener
tagManager.subscribeAsync(path, listener);
}
// Handle the tag change event
private void handleTagChange(QualifiedValue newValue) {
if (newValue.getQuality().isGood()) {
Double newTagValue = newValue.getValue() instanceof Double ? (Double) newValue.getValue() : 0.0;
setNumVal(newTagValue); // Update NumVal property
}
}
@Override
protected void onStartup() {
super.onStartup();
try {
bindTagToNumVal("[VTISControl]VTIS1/Phase Control/Phase1_Ster/Status/Phase Status");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
The tag path will not be hardcoded, but couldn't I reasonably instantiate and remove listeners for that tag every time the tag path changes? If so, should I be doing this in the GatewayHook or on the component file itself? Or do I create the TagChangeListener class (found at this forum post) in the Common directory and use it where it is needed?
Not sure, but you are definitely leaking listeners when you change the tag path (you need to unsub the prior tagpath before subscribing the new). You are also assigning to a component property directly in your listener. Expect this to eventually crash your client and/or designer.
I think you are on your own. You are on a path that I disagree with, and I therefore have insufficient motivation to study your code.