ListView scrolling issue in JavaFX2 - javafx

I'm developing a application which has a ListView which contains items which needs complex cell layouts. The cells are in variable heights and some of the cells tends to be larger than the view port height.
But when the ListView is filled with items the scroll thumb tends to resize its self while scrolling, which makes it hard to hold onto the thumb while scrolling. This happens mainly when passing through different size of cells.
This is not a problem in Swing if I create a same kind of a cell render to be used with the JList. This problem is there in JavaFX 2 and JavaFX8 both.
When looking at the VirtualFlow which is responsible for layout of the ListView and handle scrolling, it seems that the scrollbar thumb side (lenghtbar) is calculated based on the cell count and the visible cell count, which is actually a problem when it comes to lists which has variable heights of cells.
So is this the future of the scroll bar behavior for Java FX list views? or is there any solution available for this problem? Or should I try to hide the scrollbar and provide a different user interaction to scroll?

This problem is already reported under https://javafx-jira.kenai.com/browse/RT-25059 and fixed in Java8 upto some extend. So if this fix is needed on JavaFx2 we have to backport the changes under commit http://hg.openjdk.java.net/openjfx/8/controls/rt/rev/81cc13fe6f96
To get this changes in JavaFX 2.2 you need to apply the required changes on to FX2.2 VirtualFlow.java class and load those changes before the jfxrt.jar is loaded. Another approach is if you don't like to mess up with the jfxrt classes is to have you own ListView which uses your own Skin and the patched VirtualFlow version may be with a different name. But this might require lot of customization compared to first solution.
More approaches are welcome :).

Related

Side-by-side NSTableView using StackView and Constraints

I am creating an app for macOS using XIB and Swift, XCode 12.5. What I would like to achieve is a window with two NSTableViews side-by-side, having equal widths, filling the available space. A Stack View seems the obvious choice here.
I am easily able to use constraints to make a single NSTableView fill a window and resize correctly, but my difficulty is having two side-by-side NSTableViews. I've tried everything I can think of, but the symptom is always roughly the same: in Interface Builder, expanding the window, the NSTableViews grow (equally, correctly) but shrinking the window they remain at their previous maximum size.
Running this app gives a different result: the tables do actually resize correctly, but the cell sizes are out of whack. These tables are (should be) identical copies of one another: I literally copy-pasted the second one.
I have searched for information about using NSTableView inside Stack Views, but have come up empty-handed. I have probably overlooked something! I should add that I'm happy to move to Storyboard or even SwiftUI if it means being able to solve my problem, but it looks as if SwiftUI and NSTableView will complicate the matter.
I have tried to show my work here: https://github.com/toothbrush/tabletest2.

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?
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.

Remove flickering on remvoveAllElements + addElement in a group

I am adding and removing elements dynamically in a flex application
When adding an removing items in flex component there is a flickering happening on the screen(Not all the Time only on first loading of the application). On research I understood that this is because of the time delay for two updates. One for removeAllElements and other for addElement. Is there any way to make it as one update to remove the flickering issue?
thanks
It's good practice to use DataGroup as a base class for list components. The huge benefit of it is that it has virtual layout. What means if you have 1000 items in your list, framework will create only items which can be fit in current screen ( for example 20 ). And than reuse them when user scroll list. So most likely using DataGroup will solve you problem.

Flex 4 Scrollbar Skin does not resize

I'm working on a Flex 4 application and I started customizing the interface with skins to give a whole new look.
So, I've created two scrollbar skins in Flash Catalyst (one horizontal, one vertical).
Its working great when I test the application through Catalyst so I took it and imported it on Flash Builder, copied the components and defined the new skins in my css file for the HScrollbar and VScrollbar.
The skin is working, all the buttons are ok. But, the scrollbar isnt resizing for some reason. It remains in the same height I've designed it to be regardless of the content it is bound to.
It scrolls the content in all the ways it should be but it doesnt resize and the thumb isnt getting all the way down.
Also I've noticed the following.
I have a custom component acting as a list. It extends Group and contains a Scroller. So at one place of the application the Scrollthumb is getting lower than on another place where the same custom list is used.
I also have to mention that this scroller works perfectly without a custom skin.
Anyone else having similar problems?
Okay, I know you posted this a while ago but I have been scouring the internet for days looking for why the scrollbar's thumb wasn't scaling like the default scrollbar.
There are a couple things to check, first is there a set height on your thumb's skin?
If not, and this is what I was overlooking, go to your scroller skin and at the point where you add the vertical and horizontal scrollbar set the "fixedThumbSize" property to false.
I suppose that your graphic elements are defined as every single part of the scrollbar (top arrow, bottom arrow, track, etc...): in this case you should check that the elements dimensions are not fixed... they should be in % to be able to change the dimensions based on the container.

Flex renderer recycling with browser scrollbars?

Is it possible to get flex renderer recycling while using browser scrollbars?
I have a flex tree control with custom item renderers for rich editing of a server-side data structure which may have any number of child nodes. If at all possible, I'd like to avoid using a flex scrollbar if the content exceeds the viewable range, instead preferring to scroll with the browser's scrollbar. I could use javascript and ExternalInterface to resize the application when the tree's size changes, but my understanding is that this would cause renderers to be created for every row in the tree, which I would like to avoid for performance reasons.
The Flex Tree component doesn't support something like that out of the box. It will create enough renderers to fill it's entire height, assuming the data provider is that large. Since you want it to be larger than the browser window, it will create more renderers than those bounds.
If you were willing to subclass or patch the existing Tree, you could probably add new properties to override the starting value and the height used for the calculation of the number of renderers needed. I'm not sure how much work this would be, but it could be as simple as overriding a single function where this calculation happens.
Obviously, when the browser scrolls, you'd need to pass new values for the start and end values of what's displayed in your Tree.

Resources