Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFx: In TreeView Need Only Scroll to Index number when treeitem is out of View

I need to do a simple thing. I have a large TreeView. and a menu item Next and Previous. on Next I have to select next Tree Item. Tree List Look like this

-Root(set visible hide is true for root)
 --Parent 1
 ----Child 1
 ----Child 2
 ----Child 3
 --Parent 2
 ----Child 1
 ----Child 2

Now By pressing Next or previous menu item i call

myTreeView.getSelectionModel().clearAndSelect(newIndex);

By This I have manage to select next item and by

myTreeView.getSelectionModel().scrollTo(newIndex) 

i have manage to scroll to selected treeitem.

Problam:

Let I select the first item manually. after this i press next button. Now This cause a weird behavior that it always scrolls weather new selected treeitem is in view (bounds of view able area) or out of view. let assume i have large list of tree items. and my requirement is just i only want scroll happened only when new selected tree item go out of view. can any body suggest how to achieve this??

Thanks.

like image 374
Mubasher Avatar asked Mar 18 '23 20:03

Mubasher


1 Answers

This simple thing is not so simple. It is a known issue in JavaFX; see issue RT-18965.

Based on the comment in the issue, I have made it work with my own TreeView. Please note that - as in the issue comment - I have relied on internal classes within JavaFX to get my end result. There is no guarantee that these internal classes will continue to be.

First, create a new Skin that is derived from an internal class (again: dangerous):

import javafx.scene.control.TreeView;
import com.sun.javafx.scene.control.skin.TreeViewSkin;
import com.mycompany.mymodel.DataNode;

/**
 * Only done as a workaround until https://javafx-jira.kenai.com/browse/RT-18965
 * is resolved.
 */
public class FolderTreeViewSkin extends TreeViewSkin<DataNode>
{
    public FolderTreeViewSkin(TreeView<DataNode> treeView)
    {
        super(treeView);
    }

    public boolean isIndexVisible(int index)
    {
        if (flow.getFirstVisibleCell() != null &&
            flow.getLastVisibleCell() != null &&
            flow.getFirstVisibleCell().getIndex() <= index &&
            flow.getLastVisibleCell().getIndex() >= index)
            return true;
        return false;
    }
}

Second, apply that skin to the TreeView instance you are concerned about.

myTreeView.setSkin(new FolderTreeViewSkin(myTreeView));

Finally, use the new method as a condition before scrollTo:

if (!((FolderTreeViewSkin) myTreeView.getSkin()).isIndexVisible( intThePositionToShow ))
    myTreeView.scrollTo( intThePositionToShow );

This is what worked for me; I hope it can help you or anyone else.

like image 110
Ahmed Avatar answered Apr 07 '23 06:04

Ahmed