B4J Question Data not returning from Class View module, but only some data

TorontoJim

Member
Licensed User
Longtime User
I have a custom class view module that is comprised of a ListView that I create programatically, not with the designer.

This ListView is called ExplorerWindow.

When I access ExplorerWindow.Items.Size from WITHIN the class module I get an accurate count of items (my initial directory has 101 items in the ListView)

I have a subroutine that allows the Main module to access the index of the currently selected item in the ListView, Its through a class method so that they are not trying to access the ListView directly.

B4X:
Public Sub IndexURI(Index As Int) As String
    Log("index: " & Index)
    Log("size index: " & ExplorerWindow.Items.Size)
    If Index > -1 And Index <= ExplorerWindow.Items.Size - 1 Then
        Dim ap As AnchorPane = ExplorerWindow.Items.Get(Index)
        Dim thisLabel As Label = ap.GetNode(1)
        Return File.Combine(strCurrentDirectoryURI, thisLabel.Text)
    End If
    Return ""
End Sub

Any class view method that calls this sub gets the accurate ExplorerWindow.Items.Size (which is 101 items in my loaded directory)

HOWEVER ... when the Main module tries to access this public method, the ExplorerWindow.Items.Size comes back as 0. I select an item and then use the arrow keys to fire the SelecteItemChanged raised even in the Main module, and then try to use that Index with the public method and get item information.

I'm not trying to access the node directly from the Main module, I'm calling a public class method which should be Logging (for testing) the WindowExplorer.Items.Size.

Next try was to use a second sub to privately get the value of WindowExplorer.Items.Size and return it to the public method,to return it to the Main module:

B4X:
Public Sub IndexURI(index As Int) As String
    Log("index: " & index)
    Log("size index: " & ExplorerWindow.Items.Size)
    Log("remote index size: " & winexp_items_size)
    If index > -1 And index <= ExplorerWindow.Items.Size - 1 Then
        Dim ap As AnchorPane = ExplorerWindow.Items.Get(index)
        Dim thisLabel As Label = ap.GetNode(1)
        Return File.Combine(strCurrentDirectoryURI, thisLabel.Text)
    End If
    Return ""
End Sub

Private Sub winexp_items_size As Int
    Return ExplorerWindow.Items.Size
End Sub

Still no juice. When I call IndexURI from the Main module, both "size index:" and "remote index size:" report 0 items. When I call them from a method in the class module that is using the value and not returning it, then the count is not zero, its accurate.

I tried changing:
B4X:
Private ExplorerWindow As ListView

to
B4X:
Public ExplorerWindow As ListView

Still no juice.

Next test, try and directly access an item in the ListView that I know exists, because I'm looking at it in the ListView when I click on it.

B4X:
Public Sub IndexURI(index As Int) As String
    Log("index: " & index)
    Log("size indexUri: " & ExplorerWindow.Items.Size)
    Log("remote index size: " & winexp_items_size)
    Log("known item.get(1) is B4J: " & ExplorerWindow.Items.Get(1))
    If index > -1 And index <= ExplorerWindow.Items.Size - 1 Then
        Dim ap As AnchorPane = ExplorerWindow.Items.Get(index)
        Dim thisLabel As Label = ap.GetNode(1)
        Return File.Combine(strCurrentDirectoryURI, thisLabel.Text)
    End If
    Return ""
End Sub

Program exits saying:
B4X:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 0

What do I have to do to have the ListView Items Size return a value OR the listview items have contents, when something outside of the class module is trying to get that size through a class view module public method?

Every method that access the listview items size from within the class module gets data. I even raise events from the class view module To the Main module, and they work no problem. It's just when the request comes from outside of the class view module.

The part that makes it doubly confusing, is I have other public methods that are accessing Map data from the class view module, and those method are returning the data without any issues.

Is there something obscure I'm missing here, is it a matter of class view modules behaving differently than code class modules, or is this simply how it works and I have to adjust my approach?
 

Attachments

  • class_view_issue.zip
    156 KB · Views: 236

TorontoJim

Member
Licensed User
Longtime User
The variable pointing to the class view is "explorer", not "FileExplorer1". That's the eventname for the FileExplorer when you look at it in the designer view.

In process globals I declare the variable
B4X:
Private explorer As FileExplorer

Then in the Main AppStart, I initialize the class view with this:

B4X:
explorer.Initialize(Me, "fex")

When I go to the sub in question and try changing it to this:

B4X:
Sub FileExplorer1_SelectedIndexChanged(Index As Int)
    Report("Index Changed to: Index " & Index & " for " & FileExplorer1.IndexURI(Index))
    'Report("Index Changed to: Index " & Index & " for " & explorer.IndexURI(Index))
    'Report("Index Changed to: Index " & Index)
End Sub

...the name FileExplorer1 is in red and it's telling me the var is undeclared. The program won't run because FileExplorer1 is undeclared.

If I go right back up to the top of Main and rename explorer to FileExplorer1, changing all instances of the var name, then the program opens and the form loads, but nothing gets populated because I'm using the event name as the object handle.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You are adding the view with the visual designer.

Views added from a layout files should never be initialized.

The name of of the view in the layout file is FileExplorer1 (IIRC). This should match the global variable name.
Right click on the view in the abstract designer and choose Generate - Dim ...

In your current program there are two FileExplorer objects: the one created when the layout file is loaded and the "empty" object that explorer variable points to. There isn't any relation between those two object instances.
 
Last edited:
Upvote 0

TorontoJim

Member
Licensed User
Longtime User
After playing around with what you said, I see the point you are making. I initialized it, because it was a custom class view. But I'm still adding it through the designer, so I shouldn't expressly initialize it, just like anything else I add through the visual designer.

Thank you for your persistence and patience, it took a bit but I finally understood what you were saying, and where my mistake was.
 
Upvote 0
Top