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
    viewable.jpg
    21.8 KB · Views: 607
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.
 
Top