[API Review] RT-17024: Region pickOnBounds default value
Pavel Safrata
pavel.safrata at oracle.com
Thu Feb 28 06:34:17 PST 2013
Hello,
should the pickOnBounds property's default value be changed to false for
regions? This issue has been discussed several times over the last two
years and was closed a month ago as "Won't fix". Lately, new evidence
was discovered, so we are reopening the discussion once more, hopefully
for the last time.
Jira: http://javafx-jira.kenai.com/browse/RT-17024
The old public discussion can be found in the history of this alias
under subject "Region PickOnBounds default setting":
http://mail.openjdk.java.net/pipermail/openjfx-dev/2012-June/thread.html#2538
http://mail.openjdk.java.net/pipermail/openjfx-dev/2012-July/thread.html#2692
I'll try to summarize. Short version: with the current behavior, layout
containers "eat" mouse events, not rectangular panes and panes with
displaced children "eat" mouse events outside of their visible area, all
that is confusing. Recently we've discovered that the current behavior
is practically unusable in 3D. In the other hand, fixing the above is a
backward incompatible change, causing behavioral problems to existing
application. And it would have negative performance impact. Long version
follows.
*Introduction*
Region is a base class for all controls and panes. It is a Parent, but
unlike Group, it can have its own visual appearance - borders, fills,
shape. During picking, we check the children and the region itself. As
usual, the picking of the region itself has two modes - exact picking
that picks it only on places where it's physically present (there is
something visual defined), and picking on bounds which picks it anywhere
within the rectangular bounds enclosing the whole region (including all
its children). In this discussion we need to resolve if the default
value of the pickOnBounds property for regions should be switched from
true to false.
*Old arguments for switching region pickOnBounds to false by default*
(you can skip this if you remember the old discussions):
It would make region consistent with all the other nodes we have.
People often use panes only for layout purposes and they don't expect
them to "eat" mouse events. For example, I have several buttons of
different sizes and want them to be vertically aligned. So I put them to
a VBox. Now, in the rectangular area containing all the buttons, I can
see the background, but cannot click it, because the VBox is picked. I
get confused. Often it's hard to understand what area is actually
covered by the container - with children of different sizes, some layout
stretches/paddings/insets taking place etc.
The pane's bounds contain all its children. If I create a small Pane in
top-left corner of the scene with a child in bottom-right corner of the
scene, the pane's bounds cover the entire scene and I'm not able to
click on anything else than the pane and its child. I don't understand
why, because both visually and in source code there is nothing in
between the pane and the child. (This is demonstrated in the
EvilPane.java attached to the Jira issue).
We've encountered a bunch of other problems with it. For instance,
PieChart slices are implemented as regions and they have to have
pickOnBounds set to false because their bounds obscure the neighboring
slices. When writing table (which has rows implemented as regions), a
single cell with rowSpan=2 made the enlarged bounds of the row obscure
the entire row below. And so on, time to time a new confused user
appears and needs to hear the trick: call setPickOnBounds(false).
*New arguments for switching region pickOnBounds to false by default*:
The new evidence was discovered during the work on 3D. The
PickOnBounds=true is pretty unusable in 3D. If a region has any children
that are 3D or transformed in 3D, the picking won't work well. There are
two reasons for that:
In 3D (with active depth buffer), picking considers all nodes and finds
the node under cursor which is closest to the camera. Unlike in 2D, in
3D scene graph node's bounds can be closer to the camera than its
content. For example, if I place a button in a pane and rotate the
button 45 degrees along X axis, I'll be unable to click the button,
because the pane's box bounds will always be closer to the camera than
the diagonally placed button. In general, with pickOnBounds set to true
by default on regions, anything placed in a region and rotated in 3D
can't be picked (by default of course). The same applies to nodes with
varying Z translations, 3D primitives etc.
The second problem here is that a child is translated to positive
numbers along Z axis may be obscured by the region's fill. It may even
be partially obscured with the 3D rotations or 3D primitives. So to pick
the correct node visible under mouse cursor in 3D, it's just not
sufficient to check the bounds. So 3D apps would probably end up calling
setPickOnBounds(false) on all regions/panes.
*Arguments against switching region pickOnBounds to false by default*:
First of all, it is a backward incompatible change! This is a strong
reason. It will cause some behavioral problems to existing controls and
applications. Some of the existing control skins rely on the current
behavior and may misbehave after the change, it looks like nobody is
able to fully assess the potential impact. There are other things like
small icons implemented as regions (the arrow in combo box) which would
now be picked only exactly on the shape etc. Another serious issue is
that some users use empty panes for the purpose of blocking mouse
events, for example during data loading or showing in-scene dialogs. All
those things will have to be fixed in controls and user apps.
Then there is performance. Obviously, checking all the possibly complex
visuals of a region takes more time than just checking the rectangular
bounds. So changing the default value will have negative performance
impact.
Finally, if the current behavior doesn't fit, there is fairly simple
workaround - just call setPickOnBounds(false). You need to be aware of
this, and for some use-cases you'll have to do this often, but still it
lowers the push for the change considerably.
Do you want us to keep the current behavior or to do the change?
Thanks,
Pavel
More information about the openjfx-dev
mailing list