Mengsk
Mengsk

Reputation: 53

JavaFX disable TextArea scrolling

I have been trying to disable scroll bars in a text area using the code:

ScrollBar scrollBarv = (ScrollBar)textArea.lookup(".scroll-bar:vertical");
scrollBarv.setDisable(true);

But all I get is a null pointer for "scrollBarv". What am I missing?

Upvotes: 0

Views: 1959

Answers (1)

jewelsea
jewelsea

Reputation: 159576

You can't disable a scroll bar in a text area via lookups like you are trying to do.

A lookup is CSS based, which usually means it will only work after a CSS application pass has been applied. Generally, for a lookup to work as expected, a layout pass also needs to be applied on the parent node or scene. The logic in the JavaFX layout handlers for complex nodes such as controls may modify the CSS and nodes for the controls.

To understand how to apply CSS and perform a layout pass, read the relevant applyCss() documentation.

So you could do this:

textArea.applyCss();
textArea.layout();
ScrollBar scrollBarv = (ScrollBar)textArea.lookup(".scroll-bar:vertical");
scrollBarv.setDisable(true);

But even then, it would not do what you want. Because it is just a one-time call. If the user types new text into an empty TextArea until it fills the area, then a scroll bar will show up, and if the user deletes text in the text area, the scroll bar will be removed. And the new scroll bar which shows up wouldn't be found when you did your lookup because it would not have existed at that time.

Generally, the preferred alternative to performing lookups to nodes is to apply CSS style classes with the style class defining the desired attributes of the node regardless of the state it is in (and using psuedo-classes if state based CSS definitions are required). However, that probably won't work in this case as I can't see a definition for a disable attribute in the JavaFX CSS reference guide. Perhaps you might manage what you need via the visibility property, though that is unlikely as visibility is a bit different from disable.

The behavior for controlling the scroll bars is internally coded in the TextAreaSkin (which in Java 8 is not part of the public JavaFX API). You could copy or subclass the TextAreaSkin to customize its behavior and then attach your customized skin to your node. This is really the "proper" way to customize internal control behavior in the way in which you wish. A discussion of the detailed steps to achieve this is outside the scope of this answer.

But, in the end, I'm not sure how useful the behavior you desire is. Rather than disabling the vertical scroll bar, you could just disable the entire TextArea, which would be fine for most similar use-cases. Though, perhaps your use-case is different somehow in requiring only the vertical scroll bar to be disabled.

Upvotes: 2

Related Questions