Region PickOnBounds default setting
Pavel Safrata
pavel.safrata at oracle.com
Thu Jun 21 01:44:37 PDT 2012
Hi Daniel,
On 20.6.2012 21:55, Daniel Zwolenski wrote:
>>> Assuming I understand the problem then I've hit this sort of layout problem and my instinct was to look
>>> I'm not sure I agree with the bug description when it says that "both visually and in source code there is nothing in between the pane and the child". In code there is a pane. Visually there would be a pane if you set styles on it.
>> The pane from the description is small and is in a top-left corner. It can be styled, and you can see it there. There is no code that would make the pane big to cover the whole scene, there is no way to make it visible in the whole area, because it's just not there.
> I am perhaps missing something, but "Pane's bounds will then cover whole sceen" implies to me the pane is stretched, so if I styled it I would see it stretched. The description of #2 is a bit vague to me though. I guess a code example would clear this up but it probably doesn't matter that I dont understand.
The pane is not necessarily stretched to embrace all its children. I've
attached a code example that shows the problem.
>
>>> I'm guessing, for example, if this fix went in it would break all my 'glasspanes'?
>> I cannot say unless I know how your glasspanes are implemented...
> I use glass panes to block the screen in two cases: when loading and behind a light box (ie embedded dialog).
>
> In both cases my glass pane is just a pane (eg BorderPane) added to the top of a StackPane with the rest of the app added to a lower layer of the stack. In the loading case it has no children, in the dialog case it's child is the dialog.
>
> The loading one is transparent but has an in-progress cursor when you mouse over. In the dialog case, the pane is a translucent grey, though you could style it differently and transparent would be a valid style (making the fill color define if it is clickable would not be nice for me and is a little scary).
>
> In both cases the point of it is that it blocks mouse input to the scene. I'd prefer this didn't break in a future release (sorry!). If auto updating (my nemesis) wasn't on then I'd be ok for it to change and then I fix my apps before moving to a higher version but it magically working one day and not the next would be pretty nasty for me.
It would break your glass panes only if they have no fill (which I agree
is bad enough). Pane with transparent fill would still block mouse
events. I'm not sure why this is scary, this approach is used everywhere
in FX except of Region.
>
>
>>> As such, I don't think it needs to be a default attribute now that it's in place the other way round but I do think it needs to be clear and intuitive how to deal with it.
>> I'm really sad that we've let this go that far, it could have been fixed before our first release. If the decision comes that it's too late by now, the way how to deal with it will be clear (setPickOnBounds(false)), but I doubt it is (and could be) intuitive.
> For me the current default behavior seems intuitive: the pane is clickable for whatever area it takes up. I get the feeling I might be missing something here though as it is obviously a concern for some people. Sorry if I have misunderstood.
I think the attached example shows pane that is clickable in area that
it doesn't take up.
>
> For me the only problem with the current approach is that in some cases I'd like a pane used purely for layout (anchor pane as top layer of a StackPane is a prime candidate) to not catch mouse clicks but the children on it still should. Calling setPickOnBounds(false) and setShape(null) to do this is not intuitive to me but I'm glad I now know its possible as I've struggled with this before (and possibly raised a bug, will have to check).
This is exactly the most common problem that would be solved. You see
you're glad that you now know how to solve it, but other users will keep
bumping into this issue..
Thanks,
Pavel
>
>
>> Thanks,
>> Pavel
>>
>>>
>>> On 20/06/2012, at 5:41 AM, Richard Bair<richard.bair at oracle.com> wrote:
>>>
>>>> Hi folks,
>>>>
>>>> We have an issue which has been in the platform from before 2.0: http://javafx-jira.kenai.com/browse/RT-17024. A better explanation of the issue can be found on http://javafx-jira.kenai.com/browse/RT-12258. From 12258:
>>>>
>>>>> Region behaves counter-intuitively regarding mouse event delivering. It reacts on mouse events everywhere in its bounds and people are often confused by it. Here are two simple examples:
>>>>>
>>>>> 1) You create let's say HBox just because you want it to layout its children. The HBox catches all mouse events in the whole area given by its bounds. Often it's hard to understand what area it is (with children of different size or with some other layout stretches taking place).
>>>>>
>>>>> 2) You create a small Pane in top-left corner of the scene with a child in bottom-right corner of the scene. Pane's bounds will then cover whole sceen and you won't be able to click on anything else than the pane and its child. Users don't understand why, because both visually and in source code there is nothing in between the pane and the child.
>>>>>
>>>>> Moreover, region may have a shape associated and the behavior here is also strange. If you create a region with a shape inside its bounds, it's just ignored. You can also create a shape somewhere else, then it extends region's bounds and it reacts on mouse click everywhere between the shape and the region.
>>>> This issue has to do with the semantics of picking on a Region. For Region we have had pickOnBounds set to true by default, which yields the above behaviors. We can change it to false by default, but then need to update a bunch of skins (for example the up/down arrows of scroll bar, the thumb of a slider, the down arrow of a combo box button, etc) so that they switch back to having pickOnBounds set to true by default so that the target area for clicks is larger. We could just change the default for Pane and not for Region, although we use StackPane in Skins and would have to update them anyhow. It seems that for a normal layout container the behavior really should be pickOnBounds=false by default, but for UI controls usages and such you generally want it true.
>>>>
>>>> I'm not certain making this change is worth being backwards incompatible (semantically, binary compatibility would remain). But what do you think?
>>>>
>>>> Richard
-------------- next part --------------
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class EvilPane extends Application {
@Override
public void start(Stage stage) {
stage.setTitle("Evil Pane");
Pane root = new Pane();
Pane evilPane = new Pane();
evilPane.setStyle("-fx-background-color: BLUE");
evilPane.setMaxSize(50, 50);
// evilPane.setPickOnBounds(false);
Button childButton = new Button("Child of the blue pane");
childButton.setLayoutX(300);
childButton.setLayoutY(300);
Button deadButton = new Button(
"Cannot click this because blue pane covers it");
deadButton.setLayoutX(150);
deadButton.setLayoutY(150);
evilPane.getChildren().add(childButton);
root.getChildren().addAll(deadButton, evilPane);
Scene s = new Scene(root, 500, 500);
stage.setScene(s);
stage.show();
childButton.requestFocus();
}
public static void main(String[] args) {
launch(args);
}
}
More information about the openjfx-dev
mailing list