B4J Question Mouse Click on ImageView in TableView

Robert Valentino

Well-Known Member
Licensed User
Longtime User
When I do the following
B4X:
      Dim TrackInfo As TTrackInfo
       Dim FileName  As String
       
       If  Files.Size = 0 Then Return
       
       
       FileName = Files.Get(0)
       
       Files.RemoveAt(0)
       
       Dim Columns(mTableView.ColumnsCount) As Object
       
       TrackInfo = ReadMP3File(FileName)
     
       Columns(0) = (mTableView.Items.Size+1)
       
       If  TrackInfo.CoverArt <> Null And TrackInfo.CoverArt.IsInitialized Then
         Dim CoverArt      As ImageView
         
         CoverArt.Initialize("CoverArt")                ' *******  CoverArt_MouseClicked
         CoverArt.Tag       = TrackInfo
         CoverArt.PreserveRatio    = True
         CoverArt.SetSize(60, 60)
         
         CoverArt.SetImage(TrackInfo.CoverArt)
         
         Columns(1) = CoverArt
       Else
         Columns(1) = ""
       End If
       
       Columns(2) = TrackInfo.Artist
       Columns(3) = TrackInfo.Album
       Columns(4) = TrackInfo.Number
       Columns(5) = FormatTime(TrackInfo.Duration)
       Columns(6) = TrackInfo.Song
       Columns(7) = TrackInfo.FileName
       Columns(8) = TrackInfo.FilePath

       mTableView.Items.Add(Columns)

       If  Files.Size > 0 Then CallSubDelayed2(Me, "DoTracks", Files)

I get just what I wanted a Cover Art Icon that looks like below Image - 1.
Image-1.jpg

But when I click on the Image the CoverArt_MouseClicked routine does not get called

if I change the code to put the ImageView in a Pane like below
B4X:
      Dim TrackInfo As TTrackInfo
       Dim FileName  As String
       
       If  Files.Size = 0 Then Return
       
       
       FileName = Files.Get(0)
       
       Files.RemoveAt(0)
       
       Dim Columns(mTableView.ColumnsCount) As Object
       
       TrackInfo = ReadMP3File(FileName)
     
       Columns(0) = (mTableView.Items.Size+1)
       
       If  TrackInfo.CoverArt <> Null And TrackInfo.CoverArt.IsInitialized Then
         Dim CoverArtHolder  As Pane
         Dim CoverArt      As ImageView
         
         CoverArt.Initialize("CoverArt")         
         CoverArt.Tag       = TrackInfo
         CoverArt.PreserveRatio    = True
         CoverArt.SetSize(60, 60)
         
         CoverArt.SetImage(TrackInfo.CoverArt)               ' PUTTING CoverArt in Contained allows CoverArt_MouseClicked to get called - BUT my image is not right
         
         CoverArtHolder.Initialize("")
         CoverArtHolder.AddNode(CoverArt, 0, 0, -1, -1)     '  TRIED 60, 60 instead of -1, -1 but same result - NARROW box.
         
         Columns(1) = CoverArtHolder
       Else
         Columns(1) = ""
       End If
       
       Columns(2) = TrackInfo.Artist
       Columns(3) = TrackInfo.Album
       Columns(4) = TrackInfo.Number
       Columns(5) = FormatTime(TrackInfo.Duration)
       Columns(6) = TrackInfo.Song
       Columns(7) = TrackInfo.FileName
       Columns(8) = TrackInfo.FilePath

       mTableView.Items.Add(Columns)

       If  Files.Size > 0 Then CallSubDelayed2(Me, "DoTracks", Files)

NOW my ImageView mouseclicked routine gets called but the CoverArt Images look nothing like what I want or need. See Image-2

Image-2.jpg


So I am confused how to get the CoverArt to look like I want and be able to get a MouseClicked on it.

Thanks

BobVal
 

Daestrum

Expert
Licensed User
Longtime User
I have been trying this and cannot get imageview click unless it is in a pane
here's a simple example program that shows the problem
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim t,t1 As TableView ' t1 no pane for image
    Dim li,li1 As List
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.Show
    t.Initialize("tv")
    t.SetColumns(Array("picture"))
    t.SetColumnWidth(0,70)
    t1.Initialize("tv1")
    t1.SetColumns(Array("picture"))
    t1.SetColumnWidth(0,70)
    MainForm.RootPane.AddNode(t,0,0,300,300)
    MainForm.RootPane.AddNode(t1,310,0,300,300)
    li.Initialize
    li1.Initialize
    For a = 0 To 5
        Dim i As Image
        i.Initialize("c:/temp/","batman.bmp")
        Dim iv As ImageView
        iv.Initialize("iv")
        iv.SetSize(60,60)
        iv.SetImage(i)

        Dim iv1 As ImageView
        iv1.Initialize("iv1")
        iv1.SetSize(60,60)
        iv1.SetImage(i)

        Dim p As Pane ' only used in tableview t (left one)
        p.Initialize("")
        p.SetSize(60,60)
        p.AddNode(iv,0,0,60,60)
       
        li.Add(Array(p))
        li1.Add(Array(iv1))
    Next
        t.Items = li ' left tableview
        t1.Items = li1 ' right tableview
End Sub
Sub iv_MouseClicked (EventData As MouseEvent)
    Log(Sender)
    Log("imageview clicked")
End Sub
Sub iv1_MouseClicked (EventData As MouseEvent) ' never gets called
    Log(Sender)
    Log("imageview1 clicked")
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I see it too. I'm not sure why it happens but it happens in JavaFX internally.

Workaround:
1. Add a filter listener on the TableView:
B4X:
Dim r As Reflector 'jReflection library
r.Target = t
r.AddEventFilter("TableView", "javafx.scene.input.MouseEvent.MOUSE_CLICKED")

2. Get the clicked item:
B4X:
Sub TableView_Filter(e As Event)
   Try
     Dim jo As JavaObject = e
     Dim PickResult As JavaObject = jo.RunMethod("getPickResult", Null)
     If PickResult.IsInitialized Then
       Dim nw As JavaObject = PickResult.RunMethod("getIntersectedNode", Null)
       If nw.IsInitialized Then
         Dim item As Object = nw.RunMethod("getItem", Null)
         If item Is ImageView Then
           Dim iv As ImageView = item
           'your image view is here.
           Log("Found: " & iv)
           e.Consume
         End If
       End If
     End If
   Catch
     Log(LastException)
   End Try
End Sub
 
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
An alternative (if you know which column the imageview is in)
define t1 as single cell selectable
then
B4X:
Sub tv1_SelectedCellChanged (RowIndex As Int, ColIndex As Int, Cell As Object)
    If ColIndex=0 Then ' image is in col 0
        iv1_MouseClicked(Null,Cell)
    End If
End Sub
Sub iv_MouseClicked (EventData As MouseEvent)
    Log(Sender)
    Log("imageview clicked")
End Sub
Sub iv1_MouseClicked (EventData As MouseEvent,o As Object)
    Log("imageview1 clicked")
    Log("imageview1 " & o)
End Sub
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Dastrum:

This only works the first time you click on it and the cell is NOT selected.
If you click on it the cell becomes selected. But if you click again, the SelectedCellChanged never happens because it is already selected.


Erel:

Your solution works Perfectly

Thanks
 
Last edited:
Upvote 0
Top