# Accessing Ignition Component Properties, Programmatic Placement of properties

**URL:** <https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [June 28, 2022, 8:33pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324 "2022-06-28T20:33:06Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![byrnep](https://avatars.discourse-cdn.com/v4/letter/b/db5fbb/32.png) [@byrnep](https://forum.inductiveautomation.com/u/byrnep)\
**Post date:** [June 28, 2022, 8:33pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/1 "2022-06-28T20:33:06Z")

</div>

> [@Positioning components with 'x' and 'y' properties and system.gui.transform()](https://forum.inductiveautomation.com/t/positioning-components-with-x-and-y-properties-and-system-gui-transform/60773):
>
> Hi all, So I am trying to create a plot of the timing of various devices during one of our system’s runs. Start time and duration can vary among several different devices, so we have in the past listed them as horizontal rectangles of various lengths, with length proportional to on-duration. Rectangles are very easy. They have an ‘x’ and ‘width’ component, which I can bind to start and end-start respectively. The problem is labels. I would like the labels to float near the rectangles, for …

Related to the above. I am trying to get labels to overlay rectangles that I move and stretch to represent time durations of various states to our operators during a run.

If I take the left edge of the rectangle by using event.source.getComponent('rectangle').relX, and set the position with system.gui.transform, and coordspace 1, the label and rectangles' right edges are properly aligned.

If I _then_ try to sum event.source.getComponent('rectangle').relX and event.source.getComponent('rectangle').width, I get a value that seems to always be the largest possible x value my window will permit.

If I write the event.source.getComponent('rectangle').width value to a label, I see that it is, again, the width of my window. I'm guessing that the 'width' property accessible in the Vision property editor for the rectangle is NOT the '.width' attribute associated with event.source.getComponent('rectangle'). It's surprising because X and .relX work fine.

I tried listing the attributes, using **dict** but somehow the Ignition components are written in such a way that they lack the attribute dicitonary? Wasn't aware this was even possible, I even checked the Jython documentation to be sure it is the same in both versions.

What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [June 28, 2022, 8:48pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/2 "2022-06-28T20:48:13Z")

</div>

Ignition components aren't written in Jython, they are written in Java. You can deep dive into the Java Docs if you want.

You might also find this useful.

> [@Finding all available methods from a component](https://forum.inductiveautomation.com/t/finding-all-available-methods-from-a-component/9670/2):
>
> I’ve attached the introspect() function that I wrote years ago (in the FPMI days). Still handy today. I suggest you load it as a shared module, then call it like: powerTable = event.source.parent.getComponent('Power Table') shared.inspect.introspect(powerTable) inspect.py (3.09 KB) Edit: Link expired. Use the version shown below.

However, putting that aside. JavaSwing which is what Vision uses, is terrible at scaling, so choosing to use `system.gui.transform()` here is gonna be a rough road. I would strongly recommend using a Paintable Canvas.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 28, 2022, 9:02pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/3 "2022-06-28T21:02:31Z")

</div>

> [@lrose](#):
>
> I would strongly recommend using a Paintable Canvas.

💯

---

<div class="post-metadata">

**Author:** ![byrnep](https://avatars.discourse-cdn.com/v4/letter/b/db5fbb/32.png) [@byrnep](https://forum.inductiveautomation.com/u/byrnep)\
**Post date:** [June 28, 2022, 11:52pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/4 "2022-06-28T23:52:37Z")

</div>

I took one semester of Java in undergrad and that was enough to convince me never to bother with it more than was absolutely necessary. I confess to not having 100% visibility into the backend of Ignition but the scripting language is jython and the components are generally manipulable with the standard Python methods. Except \_\_ dict \_\_, and vars(), for some reason.

The _PYTHON_ function dir(), applied to the JYTHON component ‘rectangle’ returned all the available properties of the rectangle function, including the manual-undocumented ‘relWidth’ and ‘relHeight’.

For whatever reason, probably something Javonic, selecting ‘width’ or ‘height’ from a component gives you the width/height of the window (or possibly the container - my rectangles were contained by root). It’s inarguably bad nomenclature, but if that’s Java, I could believe it.

event.source.getComponent(‘rectangle’).x+event.source.getComponent(‘rectangle’).relWidth is the correct, Pythonic (but I repeat myself) answer.

interestingly,  
event.source.getComponent(‘rectangle’).relX+event.source.getComponent(‘rectangle’).relWidth  
also works. not sure what difference there is between .relX and .x, a mystery as obscure as why the ‘width’ property of an object would not refer to that object’s width, or why a python class would be created without a \_\_ dict \_\_.

Anyway, SOLVED.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 29, 2022, 12:23am UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/5 "2022-06-29T00:23:00Z")

</div>

Jython is a java-based implementation of python (the language). The python (implementation) most commonly called python is CPython, a C-based implementation of python. They are different in numerous, implementation-specific ways. Jython normally wraps java classes on the user’s behalf in ways that hide java’s true nature. That can be overridden by java programmers for gnarly cases. Oh, well.

Also, even CPython can ditch the normal ` __dict__ ` if ` __slots__ ` is defined.

I highly recommend you get over your aversion to java, or at least to the java standard library, as it is the foundation of Ignition. Use of java in jython in lieu of python stdlib is the key to its most stable deployment.

---

<div class="post-metadata">

**Author:** ![byrnep](https://avatars.discourse-cdn.com/v4/letter/b/db5fbb/32.png) [@byrnep](https://forum.inductiveautomation.com/u/byrnep)\
**Post date:** [June 29, 2022, 3:27pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/6 "2022-06-29T15:27:40Z")

</div>

@pturmel You know much more than me so I’ll take that under advisement, however, it was entirely unnecessary to do anything unpythonic to find the info I needed, which was the kernel of my question. I also know Python is built on C, as well as C, and I’m familiar with Cython.

@lrose ‘Don’t do X do Y’ in response to ‘I want to do X’ is probably the worst pathology on internet forums. It’s smug and dismissive, and if you have a full understanding of why one is better than the other it’s incumbent to first explain X, _then_ suggest and explain Y, then make your case for why you prefer Y vs X.  
‘Deep dive into the Java docs indeed’. And then when doing X turns out to be not that difficult, it looks like the reason you suggest Y is because you never learned how to do X.

To be clear again, no concrete, actionable help was provided by by this thread. I updated specifically to answer my own question and in so doing, increase the searchable documentation on one component specifically, and solving similar problems with other components using python in general.

But to dive back into the Java/Python debate:  
[Drawing Rectangles Examples with Java Graphics2D](https://www.codejava.net/java-se/graphics/drawing-rectangles-examples-with-graphics2d)  
“In Java, to draw a rectangle (outlines) onto the current graphics context, we can use the following methods provided by the Graphics/Graphics2D class: **drawRect(int x, int y, int width, int height)**”

The decision to define the ‘width’ and ‘length’ properties contrary to how they are defined on the Vision Client Browser and in Java itself (and in common colloquial English), doesn’t seem to be a Python/Java issue. By default width is width is width. The width attribute of a rectangle component in Ignition is the width of the container it is created in, and relWidth is is the width of the object. That seems to me to be just an Ignition thing, that no amount of hitting the Java books will help.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 29, 2022, 4:14pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/7 "2022-06-29T16:14:12Z")

</div>

Shape components in Vision are complicated because the _problem_ is complicated. Users want to set things up in the designer, and then have them work in arbitrary clients at arbitrary screen resolutions. The `relX`, `relY` (and corresponding `relWidth` and `relHeight`) abstractions are, ultimately, due to the same thing as in your first post - the difference in “coordinate spaces” between the designer and the runtime.  
`width` and `height` are still available because they’re core properties of _every_ Java Swing component, even though they’re not particularly meaningful in this case.

I don’t know why this information has never been put in the manual, other than that generally speaking people don’t dynamically reposition components at runtime very much. If they do, the recommendation is to use `system.gui.transform`, since it papers over this abstraction.

Another option is the Paintable Canvas, as @lrose mentioned. I would agree with this recommendation if you have the specific requirement of “drawing an arbitrary number of graphical primitives at arbitrary positions”. The paintable canvas will be both more performant and likely easier to maintain once set up.

---

<div class="post-metadata">

**Author:** ![byrnep](https://avatars.discourse-cdn.com/v4/letter/b/db5fbb/32.png) [@byrnep](https://forum.inductiveautomation.com/u/byrnep)\
**Post date:** [June 29, 2022, 4:31pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/8 "2022-06-29T16:31:25Z")

</div>

The first link was me using System.gui.transform. The issue was knowing how to define the location to which I wanted to transform the object. Not a complicated problem. The hard part was guessing what string of characters I needed to access the property, given that the string was not intuitive, and the usual tools for determining it were non-functional.

The answer, if you are a user who wants to solve a problem quickly because you have other work to do, is use ‘relX’, ‘relY’, ‘relWidth’, and ‘relHeight’. And now that solution is documented. You’re welcome.

Another answer, if you are a developer who hasn’t documented the correct answer, and has other work to do, is to tell people to teach themselves Java and use the paintable canvas. Shall I refer to the Igniton manual to learn how to use it?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 29, 2022, 4:51pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/9 "2022-06-29T16:51:48Z")

</div>

> [@byrnep](#):
>
> I tried listing the attributes, using **dict** but somehow the Ignition components are written in such a way that they lack the attribute dicitonary? Wasn’t aware this was even possible, I even checked the Jython documentation to be sure it is the same in both versions.
> 
> What am I doing wrong?

As long as we're being pedantic, the _question you asked_ in the original post was "what am I doing wrong". The suggestion was to go to the javadocs. If you `print type(yourRectangleReference)`, you get the fully qualified Java class name of the given component. If you look for that in the javadocs, you get... a [Javadoc](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.18/com/inductiveautomation/vision/api/client/components/shapes/PathBasedVisionShape.html), which lists all the properties, including `relX` and `relWidth` and everything else.

You could also use Phil's `introspect` script, also mentioned above, to get much the same information as the Javadoc:

> **Introspect**
>
> ```auto
> Python Type: <type 'com.inductiveautomation.vision.api.client.components.shapes.PathBasedVisionShape'>
> Java Type: <type 'com.inductiveautomation.vision.api.client.components.shapes.PathBasedVisionShape'>
> M: <type 'void'> setFillPaint(<type 'java.awt.Paint'>)
> M: <type 'java.awt.Paint'> getFillPaint()
> M: <type 'void'> mirrorHorizontal()
> M: <type 'void'> mirrorVertical()
> M: <type 'float'> getStrokeSize()
> M: getCenterpoint()
> returns <type 'java.awt.geom.Point2D'>
> M: <type 'void'> setBoundingRect(<type 'java.awt.geom.Rectangle2D'>)
> M: <type 'java.awt.Paint'> getStrokePaint()
> M: <type 'java.awt.Stroke'> getStrokeStyle()
> M: <type 'void'> alterDelegate(<type 'java.awt.geom.GeneralPath'>)
> M: <type 'void'> alterDelegate(<type 'com.inductiveautomation.vision.api.client.components.shapes.ShapeDelegate'>,<type 'double'>)
> M: <type 'void'> convertToPath()
> M: <type 'void'> setStrokeStyle(<type 'java.awt.Stroke'>)
> M: <type 'void'> setStrokePaint(<type 'java.awt.Paint'>)
> M: getShapeBounds(<type 'java.awt.geom.Rectangle2D'>)
> returns <type 'java.awt.geom.Rectangle2D'>
> M: <type 'java.awt.Shape'> getShape()
> M: <type 'void'> update()
> M: getDelegate()
> returns <type 'com.inductiveautomation.vision.api.client.components.shapes.ShapeDelegate'>
> M: <type 'java.awt.geom.Area'> getArea()
> M: <type 'java.awt.Shape'> getArea()
> M: <type 'void'> setDelegate(<type 'com.inductiveautomation.vision.api.client.components.shapes.ShapeDelegate'>)
> M: <type 'boolean'> isRotated()
> M: <type 'void'> paintShape(<type 'java.awt.Graphics2D'>)
> 
> From Type: <type 'com.inductiveautomation.vision.api.client.components.shapes.AbstractVisionShape'>
> M: <type 'double'> getAngleDegrees()
> M: <type 'void'> setAngleDegrees(<type 'double'>)
> M: getRotationAnchor()
> returns <type 'java.awt.geom.Point2D'>
> M: <type 'void'> setAngleRadians(<type 'double'>)
> M: <type 'void'> setRelWidth(<type 'double'>)
> M: <type 'double'> getAngleRadians()
> M: <type 'double'> getRelWidth()
> M: <type 'void'> clearTempTransmform()
> M: <type 'double'> getRelHeight()
> M: getTempTransform()
> returns <type 'java.awt.geom.AffineTransform'>
> M: <type 'void'> setRelHeight(<type 'double'>)
> M: <type 'void'> setTempTransform(<type 'java.awt.geom.AffineTransform'>)
> M: getBoundingRect(<type 'java.awt.geom.Rectangle2D'>)
> returns <type 'java.awt.geom.Rectangle2D'>
> M: getBoundingRect()
> returns <type 'java.awt.geom.Rectangle2D'>
> M: <type 'void'> setOriginalBounds(<type 'java.awt.geom.Rectangle2D'>)
> M: getOriginalBounds()
> returns <type 'java.awt.geom.Rectangle2D'>
> M: <type 'void'> setRotationAnchor(<type 'java.awt.geom.Point2D'>)
> M: <type 'double'> getRelX()
> M: <type 'void'> setRelX(<type 'double'>)
> M: <type 'double'> getRelY()
> M: <type 'void'> setRelY(<type 'double'>)
> M: <type 'java.lang.String'> toString()
> M: <type 'boolean'> contains(<type 'int'>,<type 'int'>)
> M: <type 'void'> rotate(<type 'double'>,<type 'double'>,<type 'double'>)
> M: <type 'void'> rotate(<type 'double'>,<type 'java.awt.geom.Point2D'>)
> M: <type 'void'> setBorder(<type 'javax.swing.border.Border'>)
> M: <type 'void'> repaint()
> 
> From Type: <type 'com.inductiveautomation.vision.api.client.components.model.AbstractVisionComponent'>
> M: <type 'java.util.TreeMap'> getDynamicProps()
> M: <type 'int'> getDataQuality()
> M: <type 'void'> setDataQuality(<type 'int'>)
> M: <type 'void'> updateQuality(<type 'java.lang.String'>,<type 'com.inductiveautomation.ignition.common.model.values.QualityCode'>)
> M: <type 'boolean'> isPropertyDefined(<type 'java.lang.String'>)
> M: <type 'void'> startupComponent(<type 'com.inductiveautomation.factorypmi.application.binding.VisionClientContext'>)
> M: <type 'void'> shutdownComponent()
> M: <type 'boolean'> isAntialias()
> M: <type 'void'> setAntialias(<type 'boolean'>)
> M: <type 'int'> getCursorCode()
> M: <type 'void'> setCursorCode(<type 'int'>)
> M: <type 'void'> setDynamicProps(<type 'java.util.TreeMap'>)
> M: <type 'void'> localeChanged(<type 'java.util.Locale'>)
> M: <type 'void'> setQuality(<type 'com.inductiveautomation.ignition.common.model.values.QualityCode'>)
> M: getQuality()
> returns <type 'com.inductiveautomation.ignition.common.model.values.QualityCode'>
> M: <type 'void'> setVisible(<type 'boolean'>)
> M: <type 'void'> setStyles(<type 'com.inductiveautomation.ignition.common.Dataset'>)
> M: getProperties()
> returns <type '[Lcom.inductiveautomation.factorypmi.application.binding.DynamicPropertyDescriptor;'>
> M: <type 'void'> setName(<type 'java.lang.String'>)
> M: <type 'void'> setToolTipText(<type 'java.lang.String'>)
> M: getStyles()
> returns <type 'com.inductiveautomation.ignition.common.Dataset'>
> M: getAppContext()
> returns <type 'com.inductiveautomation.factorypmi.application.binding.VisionClientContext'>
> M: <type 'java.lang.String'> getToolTipText()
> M: <type 'java.lang.Object'> getPropertyValue(<type 'java.lang.String'>)
> M: <type 'void'> setPropertyValue(<type 'java.lang.String'>,<type 'java.lang.Object'>)
> 
> ```

You hit upon an unfortunate corner case - you're trying to do something generally not recommended (dynamically repositioning things at Vision runtime) **and** you're more familiar with CPython, so your "usual tools" weren't working. The _question you posed_ was "what's wrong with the tools" and the answer you got was a different set of tools, because the tools you're used to just don't work the same way in the Jython environment. As a _bonus_, you were given a suggestion of a different avenue to go down that would also solve your problem.

You chose to engage with those suggestions in a _very_ aggressive way. I'm sorry you wasted your time searching fruitlessly at first, but you asked a specific question _and got a specific answer_.

---

<div class="post-metadata">

**Author:** ![byrnep](https://avatars.discourse-cdn.com/v4/letter/b/db5fbb/32.png) [@byrnep](https://forum.inductiveautomation.com/u/byrnep)\
**Post date:** [June 29, 2022, 5:39pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/10 "2022-06-29T17:39:20Z")

</div>

I didn’t engage with anything until after I’d found the answer. What I engaged with was the advice presented, the way the advice was presented, and the defensive response to that engagement.

dir(rectangle) gives the exact same information as the Javadoc and Introspect, we are aware of this yes? I solved the problem, so there must have been a way for me to access this info? I’m not pigheadedly refusing to solve a problem, it’s solved. And not in the way anyone suggested. In a simpler way. Without involving learning a new codebase or downloading homebrew scripts. You can keep insisting that your way is easier despite it being demonstrably not easier than typing dir() but I’m not letting you off the hook.

There were a lot of ways to fix this issue. First was properly document all of your components. ‘rectangle’ is about as simple as it gets, I assume it was one of the first defined components. If you have time to respond on a thread that has been solved four replies ago, I assume you’ve also taken time to update the manual?  
I don’t know what your constaints are, perhaps ‘width’ and ‘height’ needed to be defined as they were. I’ll just say, second, it would have been nice if they weren’t defined that way.  
Third would be define a \_\_ dict \_\_  
Fourth would be to respond ‘It looks like you’re taking a python centric approach. If you have a spare hour, check these docs, if you don’t just use dir()’

People always act surprised when folks ‘get aggressive’ as though its a werewolf thing people snap into. I got glib, unhelpful answers, despite there being a very simple solution, which if I wasn’t able to find it myself, I would be stuck. I feel entitled to be a little annoyed with the very common ways the advice was presented to me unhelpfully, and if I’m starting at a bit of a higher pitch than normal, it’s because, as mentioned, the specific way in which this advice was unhelpful has been the main pathology with seeking advice on the internet for as long as I’ve been alive.

Not for nothing? I don’t come to these forums unless I’m completely stuck. I’m sure I’m not the only one.

@pturmel, again, the advice you gave me on the previous thread was bang on. Exactly right, and looking through the dropdown of the introspect, would haveworked if I hadn’t stumbled upon dir(). Everyone else, my advice is read the python docs.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [June 29, 2022, 5:56pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/11 "2022-06-29T17:56:46Z")

</div>

I am sorry that you felt my response unhelpful. I assure you it wasn't intended to be that way.

I didn't provide a concrete and actionable answer to your question, because I didn't know one.

I do know that `dir()` doesn't always provide the information that you might be looking for, and so I provided a link to a script which provides more information than standard `dir()`. In an attempt to give you more information with which to solve your problem, since I wasn't providing a clear solution.

I also knew this:

> [@lrose](#):
>
> JavaSwing which is what Vision uses, is terrible at scaling, so choosing to use `system.gui.transform()` here is gonna be a rough road.

and this:

> [@paul-griffith](#):
>
> you’re trying to do something generally not recommended (dynamically repositioning things at Vision runtime)

And so, I _ **recommended** _ using the Paintable Canvas Component.

Please find for me where I used the verbiage 'Don't do X do Y'? I provided a known pitfall (Java Swing's Scaling) and a _ **recomendation** _ as to how to avoid that. You chose not to, that's just fine. I was only attempting to help in the best way I knew how.

> [@byrnep](#):
>
> Not for nothing? I don’t come to these forums unless I’m completely stuck. I’m sure I’m not the only one.

Many times if you're stuck, then the people on this forum will also be stuck. Expecting them to produce what you feel is in the end is a rather simple answer, is rather hypocritic seeing's as how you also hadn't found it yet and they know less about your application than you.

Again, I am sorry you felt my response was unhelpful, I will try to do better going forward.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [June 29, 2022, 6:16pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/12 "2022-06-29T18:16:31Z")

</div>

> [@byrnep](#):
>
> Not for nothing? I don’t come to these forums unless I’m completely stuck. I’m sure I’m not the only one.

That's a mistake imnsho. You should come more often. You will pick up a lot of tips, tricks and most importantly the idiosyncrasies. This forum is probably the biggest one on the internet that actively discusses with jython and more importantly the issues with certain jython implementations (like `requests` for instance and why you should use [system.net](http://system.net).\* functions instead of that). Issues like that you would run into if you only took a jython-first approach without seeing Ignition has to offer.

Anyway hope you come back ( and before you have an unsolvable issue).

---

<div class="post-metadata">

**Author:** ![byrnep](https://avatars.discourse-cdn.com/v4/letter/b/db5fbb/32.png) [@byrnep](https://forum.inductiveautomation.com/u/byrnep)\
**Post date:** [June 29, 2022, 6:23pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/13 "2022-06-29T18:23:27Z")

</div>

Guys, Learn Python.

---

<div class="post-metadata">

**Author:** ![witman](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@witman](https://forum.inductiveautomation.com/u/witman)\
**Post date:** [June 30, 2022, 5:22pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/14 "2022-06-30T17:22:45Z")

</div>

> [@byrnep](#):
>
> ‘Don’t do X do Y’ in response to ‘I want to do X’ is probably the worst pathology on internet forums. It’s smug and dismissive, and if you have a full understanding of why one is better than the other it’s incumbent to first explain X, _then_ suggest and explain Y, then make your case for why you prefer Y vs X.  
> [...] when doing X turns out to be not that difficult, it looks like the reason you suggest Y is because you never learned how to do X.

Answers that fully explain the options and pros/cons as you suggest are fantastic. And somewhat rare. Overall, I've learned more from less complete answers than the comprehensive ones--due to the rarity of the latter. The less complete/accurate answers may be because the responder doesn't know more as you suggest. Or they don't have time to post more. Or they've misunderstood the question. Or maybe I haven't presented the problem clearly. Regardless, I appreciate people giving their time to help.

If we limited responses to people who know enough to give complete, accurate answers, the subset of those who run into the questions, and then to the subset willing to give their time to answer, we wouldn't get a lot of answers.

@byrnep, I'm glad you figured it out and took the time to post your solution. Thank you. I'm certain others' contributions here will help future readers too. Thank you @lrose, @pturmel, @paul-griffith, and @bkarabinchak.psi for adding your perspectives. My first exploration of the paintable canvas (which did what I needed well) started with a suggestion to use it in another thread where the OP also ended up solving their problem another way.

---

<div class="post-metadata">

**Author:** ![byrnep](https://avatars.discourse-cdn.com/v4/letter/b/db5fbb/32.png) [@byrnep](https://forum.inductiveautomation.com/u/byrnep)\
**Post date:** [June 30, 2022, 7:43pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/15 "2022-06-30T19:43:14Z")

</div>

This was not an invitation to a philosophical debate about the relative merits of forum boards. It was a question on how to position a rectangle on a screen, and it was solved days ago.

Gentlemen, please stop responding, and please recognize that everyone who does is only demonstrating why asking a question on the internet generally, and this board specifically, is a guaranteed chore and burden compared to the very un-guaranteed chance of getting real help.

And just to cut off the next answer, I’ll remind you all, that I solved the problem myself using a function identical in output to the next most useful suggestion, from Pturmel. I really don’t need seven more people coming out of the woodwork threatening to withhold their wisdom when they contributed nothing in the first place, and the sum of what was contributed was unhelpful, irrelevant, or equal to what I was able to on my own after giving up on the forum advice.

I’ve already spoken to the HR department of one particularly enthusiastic and profane jerk who slid into my DMs and refused to leave.

Let this thread die. No one cares that you care that someone doesn’t like your forum as much as you do. I can guarantee you that no one who stumbles across this thread in the future, looking for advice on how to position components programmatically is going to care in the slightest about what follows the ‘Solved’ comment, which by length is about 93% of this thread and growing.

We’re all here because we do this for work. Go do your jobs.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 30, 2022, 8:20pm UTC](https://forum.inductiveautomation.com/t/accessing-ignition-component-properties-programmatic-placement-of-properties/61324/16 "2022-06-30T20:20:53Z")

</div>


