B4J Code Snippet Visible rows in a control

Routine to determine which rows are visible in a TableView/ListView.

Java code (for libraries etc)
B4X:
@SuppressWarnings("restriction")
    private int first =0;
    private int last = 0;

    public void getFirstAndLast(TableView<?> t){
        TableViewSkin<?> ts = (TableViewSkin<?>) t.getSkin();
        VirtualFlow<?> vf = (VirtualFlow<?>)ts.getChildren().get(1);
        first = vf.getFirstVisibleCell().getIndex();
        last = vf.getLastVisibleCell().getIndex();
    }
    public int getFirst(){
        return first;
    }
    public int getlast(){
        return last;
    }

The @SuppresWarnings("restriction") is needed as it uses VirtualFlow which is not really a normal thing to use, but as of yet they have not made a public api to return these values.

B4J code for TableView visible items
B4X:
    ' t,tvs and vf defined as JavaObject
    tvs.InitializeStatic("com.sun.javafx.scene.control.skin.TableViewSkin") ' JavaObject
    vf.InitializeStatic("com.sun.javafx.scene.control.skin.VirtualFlow") ' JavaObject
    t = table1 ' TableView to look at
    tvs = t.RunMethodJO("getSkin",Null) '  get skin from TableView
    vf = tvs.RunMethodJO("getChildren",Null).RunMethodJO("get",Array As Object(1)) ' get virtual flow from skin
    first = vf.RunMethodJO("getFirstVisibleCell",Null).RunMethod("getIndex",Null) ' get first from virtual flow
    last = vf.RunMethodJO("getLastVisibleCell",Null).RunMethod("getIndex",Null) ' get last from virtual flow
    Log("First: "& first & " Last: " & last) ' just display values

B4J code for ListView visible items
B4X:
    ' l,lvs, vf as JavaObject
    lvs.InitializeStatic("com.sun.javafx.scene.control.skin.ListViewSkin") ' JavaObject
    vf.InitializeStatic("com.sun.javafx.scene.control.skin.VirtualFlow") ' JavaObject
    l = list1 ' ListView to look at
    lvs = l.RunMethodJO("getSkin",Null) '  get skin from ListView
    vf = lvs.RunMethodJO("getChildren",Null).RunMethodJO("get",Array As Object(0)) ' get virtual flow from skin
    first = vf.RunMethodJO("getFirstVisibleCell",Null).RunMethod("getIndex",Null) ' get first from virtual flow
    last = vf.RunMethodJO("getLastVisibleCell",Null).RunMethod("getIndex",Null) ' get last from virtual flow
   Log("First: "& first & " Last: " & last) ' just display values

Screenshot below is an example of what it can be used for.
 

Attachments

  • viewable.jpg
    21.8 KB · Views: 619
Last edited:

Daestrum

Expert
Licensed User
Longtime User
Added B4J code example.
 

Daestrum

Expert
Licensed User
Longtime User
Added ListView B4J example code.
 

stevel05

Expert
Licensed User
Longtime User
Hi @Daestrum I came across similar code on the internet and had just finished converting when I found this post.

Do you notice a difference in results between debug and release modes? In my tests on a TableView using JavaObjects in Debug mode, it reports 2 extra rows that are not visible. Any chance you could test it on your running code and see if it is the same?

Thanks
 

Daestrum

Expert
Licensed User
Longtime User
I haven't tried yet, but I did notice it reports the start/end rows even if you can't really see them (they seem to only need 1 pixel on the view to be counted).
I may look at the scroll function and make it just scroll one complete row instead of the 'smooth' scrolling.
 

stevel05

Expert
Licensed User
Longtime User
I have looked briefly at this and couldn't find a way to scroll just one row, the ScrollTo function makes sure that the required row is somewhere in the view, but getting it where you want it seems problematic.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…