Question

ABOUT

Good morning, again, Stackoverflow community. I move here (again) to bring a bit of disorder to our thinking minds. I'm currently studying on the customization and creation of JavaFX controls. Got a great success in creating my own controls, and am very happy with the results. However, when I started trying to customize existing JavaFX controls, things began to get complicated.

THE PROBLEM

We know that the controls in Oracle package are extremely efficient, but unfortunately for me, they are boring. I tried to modify their appearance, and for this, at first I started using CSS styling, which was something very easy to do. I got the expected appearance, but things still seemed boring.

The controls seemed to change their states abruptly, no animations, no effects of state transition, nothing of the sort. When I tried to start adding some animations, I realized that some controls are made up of different components.

Let's take for example the ScrollBar control. ScrollBar consists of two buttons, thumb, track, and trackbackground. These components are considered substructures, as mentioned in JavaFX CSS own documentation (also mentioned in the "javafx.scene.control" topic), and can easily be accessed with the greater than character (>). Even having access to these types of substructures for CSS styling, I ran into problems trying to access them in pure Java code.

And for what reason I try to access those components? Well, I want to have control of the situation to be able to animate and add more components to certain specific cases. Imagine I have the following stylized scroll bar:

IMAGE

MIRROR 1 & MIRROR 2

I wish I could animate some of the components on this scroll bar. I would like that when the user clicks on the arrows, they were moving in animated form. Also like that when the mouse was over the arrows and thumb, they initiate an effect of blur, but quickly and lightly.

A strange case that puzzled me was when I tried to stylize Button. I could style the Button class via CSS, but for the existing text within Button, I could not even apply an effect on it via CSS. It seems to me that there is a substructure of text inside Button is therefore unattainable applying CSS effects.

POSSIBLE SOLUTION

In my quest for achieving that, I ended up finding AquaFX and its source code. Found that AquaFX developers appear to have used a method called "lookup", from Parent class, to try to find in Java code the existing substructures of a skin. Many of the substructures of existing skins are the type StackPane, something I really do not understand. In my attempt for obtaining such a reference, I came across the following code snippet (for ScrollBarSkin subtype, for instance):

StackPane thumb = (StackPane) super.getSkinnable().lookup(".thumb");

In fact, I was able to get the reference to the substructures of ScrollBar, for example, but there are still certain things that bother me.

THE FINAL QUESTIONS

Even having found a way to get references to substructures, as I've mentioned before, I still have some questions (or would not make sense for me to start a question here in the community):

  1. For what reason I can not access the existing substructure text Button (if it exists)?
  2. For what reason most (if not all) existing substructures are a StackPane?
  3. Using the method lookup from Parent, is really a correct (or best, or ideal) way to make some changes in the appearance of a control and add some animations?

Note: Some of the users here may end up finding unnecessary the placement of 3 questions in a single new question created in the community. However, both 3 questions deal on the same subject, ie, on the proper customization of an existing control.

I do not mean here that the AquaFX developers are incompetent. No way! I am new to this subject of editing and customizing existing controls, and so I'm trying to understand more about it. I found almost no study material on the internet that gave me some confidence, and I know that here we have a whole community of expertise on the subject that can help us (There are even people here who work in Oracle, or have friends there).

Was it helpful?

Solution

1. For what reason I can not access the existing substructure text Button (if it exists)?

Because the Button is a "text" itself. The Button extends ButtonBase and that one extends Labeled. Read the related javadocs for more info. To manipulate text properties use -fx-text-* css selectors. However to animate the text of the button, the proper way will be setting the graphic node of button, and animating this graphic node.

2. For what reason most (if not all) existing substructures are a StackPane?

IMO, due to the reason that the StackPane automatically puts its children back-to-front stack with alignment Pos.CENTER, which are appropriate in most use cases.

3. Using the method lookup from Parent, is really a correct (or best, or ideal) way to make some changes in the appearance of a control and add some animations?

This is a preferred way (i.e. api way) of getting the child from its parent container. If you are going to implement your own approach, likely will end up with the same solution. So you can get the child only once and keep reference to it on further usages.
The lookup() method is implemented in Node and overridden in Parent (JavaFX 2.2). The usage can be seen at Usage of lookup. The lookup method uses the method Selector.createSelector(). By investigating these source code (bit old versions), can do some conclusions. If you have improvement proposals or found bugs, you can file them at jira issue tracker.

However if you know the parent's node graph structure you can do something like child = parent.getChildren().get(4).getChildren().get(12); and so on of course.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top