B4J Question Tableview select multiple rows

raphipps2002

Active Member
Licensed User
Longtime User
Is it possible to select multiple rows on a tableview then scroll through the the table identifying those rows selected.
;)
 
yes - see this example (needs javaobject library)

Code: Copy
Dim jo As JavaObject = TableView1
Dim sm As JavaObject
   sm = jo.RunMethod("getSelectionModel",Null)
Dim sm1 As JavaObject
   sm1.InitializeStatic("javafx.scene.control.SelectionMode")
   sm.RunMethod("setSelectionMode",Array(sm1.GetField("MULTIPLE")))
' the following 3 lines ONLY work in release mode and will select rows 1, 2 and 5
sm.RunMethod("select",Array(1)) ' select row 1
sm.RunMethod("select",Array(2)) ' select row 2
sm.RunMethod("select",Array(5)) ' select row 5
' to add rows from mouse click use ctrl+click otherwise selection is reset

' get selected rows from table as list
Dim l As List
l.Initialize
   l.AddAll(sm.RunMethodJO("getSelectedItems",Null))

' display the data in the rows
Dim ss As String = ""
For Each o() As Object In l
   For Each o1 In o
      If ss="" Then
         ss = o1
      Else
         ss = ss & "-" & o1
      End If
   Next
Log(ss)
ss=""
Next
...
 
Last edited:
Upvote 0
ok thanks....I have included this in my code but cant get it to work. When you say 'only works in release mode' what does this mean? How do i set and what do it set to make release mode? on my form the user selects from two datepickers; from and to. jo1 and jo2.

1) Scrolling from row 1 to the end of table, looking for column(1) which is a date column. If date is between A and B I want to select it
2) I wasnt sure if tblCB.selectrow = i might interfere with the code you gave me, so i created a list of all rows within the date range then
3) for each j finds the row number and then your code - jo.RunMethodJO("getSelectionModel",Null).RunMethod("select",Array(j))
4: Display the data in the rows only shows last row

But all it does is highlight the last row :(


Code: Copy
Try
        Dim jo1 As JavaObject = dtprangeFrom
        Dim jo2 As JavaObject = dtpRangeTo
        Dim sDate1 As String = jo1.RunMethod("getValue", Null)
        Dim dDate1 As Long = DateTime.DateParse(sDate1)
        Dim sDate2 As String = jo2.RunMethod("getValue", Null)
        Dim dDate2 As Long = DateTime.DateParse(sDate2)
    Catch
        msg.Show("Select date range","Date range error")
        Log(LastException)   
        Return
    End Try
   
        Log("Period from " & DateTime.Date(dDate1) & " to " & DateTime.Date(dDate2))
       
    'select row
    Dim jo As JavaObject = tblCB
    Dim sm As JavaObject
    sm = jo.RunMethod("getSelectionModel",Null)
    Dim sm1 As JavaObject
    sm1.InitializeStatic("javafx.scene.control.SelectionMode")
    sm.RunMethod("setSelectionMode",Array(sm1.GetField("MULTIPLE")))

   
    Dim Li As List
    Li.Initialize()
   
   
    For i = 1 To tblCB.Items.Size-1
       
        Log("row selected is " & i)
        tblCB.SelectedRow = i
        Dim row() As Object = tblCB.SelectedRowValues
        Dim DT As Long = DateTime.DateParse(row(1))
   
        Log("Transaction selected is " & row(0) & " " & row(1))
        If DT >= dDate1 And DT <=dDate2 Then
            'Now select the actual row
            Li.Add(i)   
            Log(i & " is in date range" & DateTime.Date(DT))
        End If   
    Next
   
    For Each j In Li
        Log("selecting item row " & j)
        jo.RunMethodJO("getSelectionModel",Null).RunMethod("select",Array(j))
    Next
           
    'Get selected rows from the table as list
    Dim l As List
    l.Initialize
    l.AddAll(sm.RunMethodJO("getSelectedItems",Null))
   
    'Display the data in the rows
     Dim ss As String = ""
    For Each o() As Object In l
        For Each o1 In o
            If ss = "" Then
                ss=01
            Else
                ss = ss & "-" & o1
            End If       
        Next
        Log(ss)
        ss = ""
    Next





:)
 
Upvote 0
Release mode as in compiled and run.
Normally you use B4J in debug mode (the box above edit window normally says Debug) you have to select release for the select rows to work.
I have no idea as to why, as setting them from js works even in debug mode.
 
Upvote 0
If you ctrl+click on the tableview, does it select multiple rows ?
 
Upvote 0
Yes it does....but for some reason it has started to work. I am sure its something to do with dateformat...further investigation need...but I getting somewhere

thanks!
 
Upvote 0
Good :)
I can show you the equivalent code using nashorrn js, much easier to read and it can filter and select in one go

(when I say easier, I mean for me, but maybe not for others :) )
 
Last edited:
Upvote 0
yes please! Its strange you know because sometimes it works then I close app re-complie and it doesnt work! very odd! But it is working as I want thanks very much
 
Upvote 0
Well....the code seems to be working better...but one thing....why is it that the last item in the tables always ends up 'visually' highlighting the last row. But not actually selecting it as far as the code is concerned. How can I stop this?

:)
 
Upvote 0
I am not sure, it doesn't happen when I use js version to select rows
 
Upvote 0
the js version
Code: Copy
' in globals
Dim nash As jInvokeNashorn    ' in libraries under jscriptengine
Dim scr As String

The actual code
Code: Copy
scr = $"
   load("fx:base.js")
   load("fx:controls.js")
   load("fx:graphics.js")

function selectRows(table,from,to){
   table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE)
   for each(i in table.items){
       if (i[0] >= from && i[0] <= to){ //compare col 0 to value
          table.getSelectionModel().select(i)
       }
    }
}

function selectedPrint(table){
   table.getSelectionModel().getSelectedItems().forEach(function(aa){print(aa[0],"-",aa[1])})
}

function getSelected(table){
   return table.getSelectionModel().getSelectedItems()
}
"$

nash.InitInvocable(scr)
nash.Invoke("selectRows",Array(TableView1,3,6))
nash.Invoke("selectedPrint",Array(TableView1))
Log(nash.Invoke("getSelected",Array(TableView1)))
 
Last edited:
Upvote 0
Ok so I tried the code But nothing is selected. My table is called tblCB. I played with the function row numbers currently 1 to 6...but nothing selected

When I manually selected rows using ctrl-click, the log did reveal the rows selected. But in the log I had this which i have seen before and have a feeling its not correct

In my table col 0 is either I and E

and col 1 is a date

LOG

I - 2015-11-05
[[Ljava.lang.Object;@1d9e25bd]
E - 2015-12-02
[[Ljava.lang.Object;@27c8edb1]

Code

Code: Copy
scr = $"
   load("fx:base.js")
   load("fx:controls.js")
   load("fx:graphics.js")

    function selectRows(table,from,to){
       table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE)
       for each(i in table.items){
           if (i[0] >= from && i[0] <= to){ //compare col 0 to value
              table.getSelectionModel().select(i)
           }
        }
    }

    function selectedPrint(table){
       table.getSelectionModel().getSelectedItems().forEach(function(aa){print(aa[0],"-",aa[1])})
    }

    function getSelected(table){
       return table.getSelectionModel().getSelectedItems()
    }
    "$

    nash.InitInvocable(scr)

    nash.Invoke("selectRows",Array(tblCB,1,6))
   
    nash.Invoke("selectedPrint",Array(tblCB))

    Log(nash.Invoke("getSelected",Array(tblCB)))
 
Upvote 0
in this line
nash.Invoke("selectRows",Array(tblCB,1,6))
the 1 and 6 are the limits
ie the col.value is compared to the 2 values, it must be between 1 and 6 in this case

this line chooses which column you are comparing
if (i[0] >= from && i[0] <= to)
In this case its column 0

It looks like you need col 1 which would be i[1]

if column holds a string which is a date, you could pass the date range to the function in place of the 1 and 6
ie
nash.Invoke("selectRows",Array(tblCB,startdate,enddate))
or
nash.Invoke("selectRows",Array(tblCB,"2015-01-01","2015-06-06"))

or replace
Code: Copy
function selectRows(table,from,to){
    table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE)
    for each(i in table.items){
       if (i[0] >= from && i[0] <= to){ //compare col 0 to value
          table.getSelectionModel().select(i)
       }
    }
}
with
Code: Copy
function selectRows(table,col,from,to){
    table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE)
    for each(i in table.items){
       if (i[col] >= from && i[col] <= to){ //compare col.value to limits
          table.getSelectionModel().select(i)
       }
    }
}
and call with
nash.Invoke("selectRows",Array(tblCB,1,"2015-01-01","2015-06-06"))
and you can specify the column to compare in the call ( the 1 as second parameter)

this code
Code: Copy
function selectedPrint(table){
    table.getSelectionModel().getSelectedItems().forEach(function(aa){print(aa[0],"-",aa[1])})
}
simply prints out col 0 value "-" col 1 value
again the aa[0] and aa[1] specify the columns to print (col 0 and col 1 in this case)

The last routine getSelected(table) simply returns a list containing all of the selected rows (each item is an object containing the entire row)
 
Last edited:
Upvote 0
Ahh I see. Silly me! Ok I get it. But in my table column 1 shows a date. ie. 2015-11-01. So, I need to convert that column value to a tick value datetime.dateparse("2015-11-01") = tickvalue. Then compare this with the datepicker's value selected by user again converted to a tick. pickerfrom to pickerto

I presume therefore that as my date column is col 1 i need this

Code: Copy
function selectRows(table,from,to){
   table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE)
   for each(i in table.items){
       if (i[1] >= from && i[1] <= to){ //compare col 0 to value
          table.getSelectionModel().select(i)
       }
    }
}


Code: Copy
    nash.InitInvocable(scr)

    Try
        Dim jo1 As JavaObject = dtprangeFrom
        Dim jo2 As JavaObject = dtpRangeTo
        Dim sDate1 As String = jo1.RunMethod("getValue", Null)
        Dim dDate1 As Long = DateTime.DateParse(sDate1)
        Dim sDate2 As String = jo2.RunMethod("getValue", Null)
        Dim dDate2 As Long = DateTime.DateParse(sDate2)
   
    Catch
        msg.Show("Select date range","Date range error")
        Log(LastException)   
        Return
   
    End Try

    nash.Invoke("selectRows",Array(tblCB,dDate1,dDate2))
   
    nash.Invoke("selectedPrint",Array(tblCB))

    Log(nash.Invoke("getSelected",Array(tblCB)))
 
Upvote 0
What data type is col 1? do you just put a date field into it or a string?
 
Upvote 0
I would just convert the datepicker output to a string and use that to compare. (not used datepicker much but suspect the value can be like 2015/2/21)

Also you could change the if line in selectRows(table...) to
if (i[1] >= (from<to?from:to) && i[1] <= (to>from?to:from))

Then, if the dates are put in wrong instead of from, to they go in as to , from
the above line will still select the correct rows as it will use the earliest date as 'from' and the later date as 'to'.
 
Last edited:
Upvote 0
Thanks for the tutorial! :)

Can I ask...how do you DESELECT and item?

Select
jo.RunMethodJO("getSelectionModel",Null).RunMethod("select",Array(j))

DESelect
jo.RunMethodJO("getSelectionModel",Null).RunMethod("DEselect",Array(j))????

:)
 
Upvote 0
jo.RunMethodJO("getSelectionModel",Null).RunMethod("clearSelection",Array(j))
 
Upvote 0
Back
Top