[Gambas-user] GAMBAS rules! (And a couple of questions about listboxes and control "arrays")

Doriano Blengino doriano.blengino at ...1909...
Fri Jan 1 09:46:13 CET 2010


Bill Richman ha scritto:
> Well, the "list view" suggestion worked wonderfully!  Thank you!  I had 
> wondered how a "list view" differed from a "list box".  Now I know...  
> X-)  I had been using an SQL request to populate a list box; I just 
> didn't realize that there was a control available that allowed you to 
> keep track of another value in a way not visible to the user.  I'm 
> trying to implement an array of the button objects, but I'm a little 
> confused.  I need the array to be available to all of the SUBS in the 
> class where they were created (I hope I'm using the right terminology - 
> I need them to be visible to all of the subroutines associated with the 
> form they were created on).  If I try "PUBLIC aButtons[150] AS Object" 
> at the top of the code, like I do for all my other variables shared 
> within the class, I'm told "Arrays are forbidden here!".  Is there 
> something else I should be doing?  Since the form controls are what are 
> calling the subs, it seems like I can't pass the whole aButtons array to 
> the sub triggered by the event (a button click) since the form won't 
> know about it if it's declared only inside the sub where the buttons 
> were first created, right?
>   
I understand your problem: you are coming from another programming 
language, and you are trying to use the other language's concepts.
Gambas does not implement certain things, and does implement others.

You have a lot of buttons, so it is better to create them from code, as 
Fabien suggested:
> For i = 0 to 144
> > hButton = New Button(me) as "button"
> > hButton.Tag = i
> > aButtons.Add(hButton)
> >
> > Next
> >
> >
> > aButtons[40].Text
> >
(note that in the code suggested 145 buttons are created, not 144...)

To store the 144 handles you use an array of objects. In gambas you can 
not declare typed array of objects, only generic array (or lists).
Put this declaration at the beginning of the class:

        private aButtons as new Object[]

Note that "aButtons" is not an array, but an object, and as such you 
must instantiate it with NEW. Fortunately you can do it at the same time 
as the declaration.

In the above cycle you will want to set other properties, like X, Y and 
Text. The Tag property will be handy later.

Now, you want to assign event handlers to your buttons. When creating 
the buttons, each one is created with NEW and a strange clause "AS 
blahblahblah", in this case AS "button". This AS clause (which is not 
mandatory) tells gambas that events raised by the button will be named 
button_xxxxx, where xxxxx is the name of the event. To get your handler 
execute when a button is clicked, you write:

    public sub button_click()
      ...
      ...
    end

Every time one of those buttons is clicked, the button_click subroutine 
is executed. But inside that subroutine you must know what button was 
clicked, if the buttons all do different things. Fortunately again, 
every time an event is fired a hidden variable named LAST is set: it 
contains a reference to the object which raised the event. So use things 
like this:

    public sub button_click()
      print "Clicked button #" & LAST.Tag
      print "The label of the button is " & LAST.Text
      ...
    end

May be that you don't need at all to store the reference of the buttons 
(aButtons.add(...)), because in the text and tag properties of the 
buttons themselves you can put enough informations to do your job. But, 
if you want, you can use the tag property to get back to the handler of 
the button: we used the tag property to store the index of the button 
inside the array. Suppose that you want to remember, for later use, what 
was the last button clicked:

    private last_clicked_button as Button

    public sub button_click()
      print "Clicked button #" & LAST.Tag
      last_clicked_button = aButtons[LAST.Tag]   ' Tag is an index 
inside the array

      ' but the following is the same... faster and cleaner
      last_clicked_button = LAST

    end

Hope this is enough to get you started. A couple thing to better 
clarify: the array (or list) aButtons, and the variable LAST, are not 
strong typed. In gambas all the class identifiers are dynamic, so the 
compiler does not know exactly what such an object is. It will let you 
write things that will be checked only at runtime. So, in 
button_click(), you can write "LAST.NonExistent = false". The compiler 
will be happy about that, and you will get a run-time error. The 
Object[] class lets you store handlers for other objects, and you can 
mix several types of objects in the same array. This is useful, but it 
can lead to errors. The second thing is that LAST is the most easy and 
clear way to access an object inside an event handler. If you use LAST, 
you can change the name of your object and only have to change the name 
of the subroutine, not all the code inside it.

Regards,

-- 
Doriano Blengino

"Listen twice before you speak.
This is why we have two ears, but only one mouth."





More information about the User mailing list