enforcer technolgy wrote:

> I'm trying to write a small FXRuby program that will
> capture 6 pictures from a web source and place them as
> buttons on my window. After that I want to have the
> buttons to update with a new picture once every second
> or so.

<... snip ...>

> in the create method is a thread that is supposed to be
> updating button 1 every second, (It will hopefully be
> expanded to all 6 buttons an a round-robin fasion) 
> But the picture on the button is not updating and I
> can't figure out why. I've tried everything like
> repaints and refreses and it simply ignores the new
> button information. Why? Can anyone help?

Let's focus on the thread that you set up in the TestWindow#create 
method since that's where the problem lies. Your version of the thread 
procedure looks like this:

     @photo1Thread = Thread.new(@photo_array[1]) do |photo1|
       while true
         photo1 = FXButton.new(@picture_matrix,
           "photo 1", create_photo_icon(1),
           @app, FXApp::ID_QUIT,
           ICON_UNDER_TEXT|JUSTIFY_BOTTOM)
         sleep(1)
       end
     end

The first problem is that you're constructing a new FXButton instance 
every time the "while" loop runs, when all you really want to do is 
replace the old icon with a new one. So the first change is to modify 
the button (photo1) directly:

     @photo1Thread = Thread.new(@photo_array[1]) do |photo1|
       while true
         photo1.icon = create_photo_icon(1)
         sleep(1)
       end
     end

The next change has to do with FOX's two-step construction and creation 
process (see http://www.fox-toolkit.org/faq.html#ILLEGALICON). Since 
your TestWindow#create_photo_icon constructs the icon but doesn't call 
create() on it, we need to be sure to do that:

     @photo1Thread = Thread.new(@photo_array[1]) do |photo1|
       while true
         new_icon = create_photo_icon(1)
         new_icon.create
         photo1.icon = new_icon
         sleep(1)
       end
     end

Finally, one more possible change related to memory use. When you 
replace the icon previously stored on the button with the new_icon, the 
old one is no longer needed and so at some point it will be 
garbage-collected. However, if your images are large and you want to 
keep the memory use low as much as possible, you can force the GC to run 
as soon as you switch icons by adding a call to GC.start:

     @photo1Thread = Thread.new(@photo_array[1]) do |photo1|
       while true
         new_icon = create_photo_icon(1)
         new_icon.create
         photo1.icon = new_icon
         GC.start
         sleep(1)
       end
     end

A side note, unrelated to this question, is that you don't have to save 
a reference to the application in an instance variable (@app). It is 
always available via the getApp() instance method, e.g.

     def create_photo_icon(i)
       getImageData(i)
       icon = FXJPGIcon.new(getApp(),
         File.open("photo#{i}.jpg", "rb").read)
       icon.scale(120, 150)
       icon
     end

Hope this helps,

Lyle