
there are 3 "shapes", actually the green square pair is a group, here is the relevant code
All "shapes" have the save event handler, you are probably wondering if it is the same as the one showed previously here, which looks like
But sadly it will only work for the
rect
node as the other two do not have a set of [x,y] properties (as a matter of fact an exception will be thrown), so what can we do to solve this? Luckily these operations support transformations so we may attach a translate
transformation to them. Ok, but setting [x,y] is much simpler no? and surely it would be the same case if we could access the centre's coordinates of the star, right? Lastly, there is a gotcha using translate, how do we find out the correct offsets to set the relative [x,y] ?Fear not because this is exactly what this post is about, all of these problems can be solved one at a time. All "displayable" operations (shapes, outlines, images and groups) share a common ancestor that provides a new set of methods useful in this situation
- hasCenter() - returns true if the operation has [cx,cy] properties
- hasXY() - returns true if the operation has [x,y] properties
- bounds - returns the bounding rectangle, this value is calculated after the operation has been executed, so you can't access it with a
beforeRender
handler (it will be null).
The trick is storing the [x,y] coordinates of the shape's bounds the first time the event is processed, as they will be updated during the next repaint, making a mess if you use them as is. In order to solve this problem operations (and filters) now have a built-in extra set of properties (the
props
property in shape) that work pretty much as client properties do for Swing components, they are even observable too thanks to ObservableMap, so don't forget to register a PropertyChangeListener with props
if you want to receive notifications when a key is updated. Note how named nodes are also used to query for a translation node, either to create a new one or update its settings.Keep on Groovying!