Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Using Threads

using thread

  • Please log in to reply
16 replies to this topic

#1 toto_7

toto_7

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 244 posts

Posted 20 November 2011 - 03:44 PM

Hello,

Building a project and I have stuck on a part now, where when user press a button, the interface starting from it's first status and each 1 sec. moving to the next, until reach the current. Imagine something replay with chess. Replay the movements that made so far. So I have these lines...
synchronized(model){
		for(int i=0; i<model.userStates.size(); i++){
			try {
				Thread.sleep(1000);					
				model.currentState = model.userStates.get(i);
				model.notify();		
			}
			catch (InterruptedException e1) {}
		}
}
My problem is that when press the button, remain pressed (no update on interface) and at the end released. Tried constant number in get(), ex '0' and with 4 elements in the list, after 4 sec. the interface change to very first status (0). What I'm doing wrong, or what need to change?

Thank you
  • 0

"Programming is like **. One mistake and you have to support it for the rest of your life."

-Michael Sinz

#2 wim DC

wim DC

    Roar

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 2681 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Python

Posted 21 November 2011 - 12:47 AM

I think you'll need a construction like this:
public void actionPerformed(ActionEvent e){
        [COLOR=#40e0d0][B]new Thread(new Runnable()
        {
            @Override
            public void run()
            {[/B][/COLOR]
                //Code here
                //for(....){ start loop
                [B][COLOR=#ff8c00]SwingUtilities.invokeLater(new Runnable()
                {
                    @Override
                    public void run()
                    {[/COLOR][/B]
                        //update UI here
                    [B][COLOR=#ff8c00]}
                });  
               [/COLOR][/B]//}end of loop 
            [COLOR=#40e0d0][B]}
        }).start();[/B][/COLOR]
    }
Or maybe invokeAndWait(..)

Why?
The whole Swing GUI is run in one thread. It's created, build, refreshed/repainted in it.
Inside the ActionPerformed() you're also in that thread. Meaning that as long as you're looping in
the ActionPerformed() your GUI won't / can't refresh because you're keeping the "GUI-thread" busy with the loop.

Solution is to start a new thread and loop inside this thread so the "GUI-thread" is free (That's the blue part). And when you DO need to update the GUI,
you can do so by using the SwingUtilities, that will make sure that the code to update the GUI happens in the "GUI-thread" (That's the orange part).

Edited by wim DC, 21 November 2011 - 04:08 AM.

  • 0

#3 toto_7

toto_7

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 244 posts

Posted 21 November 2011 - 08:04 AM

Thanks a lot wim DC, now the only problem is that cannot use variable (i) from for loop inside run() method. Getting this error "Cannot refer to a non-final variable i inside an inner class defined in a different method"


UPDATE: Ignore my previous post, created a final int variable inside the for loop and initialise according this. Is working, also change it to .invokeAndWait()...Don't know the difference (need to check API), but is working. Thanks again :)
toto_7
  • 0

"Programming is like **. One mistake and you have to support it for the rest of your life."

-Michael Sinz

#4 fread

fread

    Programming God

  • Senior Member
  • PipPipPipPipPipPip
  • 897 posts
  • Location:Trinidad and Tobago
  • Learning:C, Java, C++, C#, PHP, Python, PL/SQL

Posted 21 November 2011 - 08:30 AM

A good practice is to write you code in such a way that the gui code is in seperate thread from the 'everythingelse' code.
  • 0

#5 toto_7

toto_7

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 244 posts

Posted 21 November 2011 - 04:30 PM

Hello fread, thanks for the advice, I'm using MVC model for my code, if that what you mean.

wim DC, code is working but sometimes, GUI stuck for a while and sometimes works fine. For example if program needs to show 4 steps with Thread.sleep(1000) sometimes, from step 1 jump to step 3 or 4 but the time is correct (I mean from step 1 jump to step 3 but takes 3000 to show the change). Is that a problem of Thread or is something wrong in the code?
  • 0

"Programming is like **. One mistake and you have to support it for the rest of your life."

-Michael Sinz

#6 lethalwire

lethalwire

    while(false){ ... }

  • Senior Member
  • PipPipPipPipPipPip
  • 766 posts
  • Programming Language:C, Java, PHP, JavaScript
  • Learning:PHP

Posted 21 November 2011 - 05:19 PM

Any type of calculations should be maintained in another thread. Any type of drawing/changing the GUI should be done in the event dispatch thread.
Why?

When you try to do long drawn out calculations, the event dispatch thread( the thread that does all of the drawing to the gui) gets put on hold while the other threads finish.
During this hold, it appears the program freezes. (No drawing to the gui is done)
  • 0

#7 fread

fread

    Programming God

  • Senior Member
  • PipPipPipPipPipPip
  • 897 posts
  • Location:Trinidad and Tobago
  • Learning:C, Java, C++, C#, PHP, Python, PL/SQL

Posted 21 November 2011 - 05:53 PM

A decent example might be a typical game loop. Take a look at Tetris.

[ATTACH=CONFIG]4333[/ATTACH]

All of the logic takes place in mid-section(game-play area) of the GUI.

Without dropping a single block you will need to be able to make this window or some variation of it. The details of of the GUI are never interrupted by the details of the game-play. This is where you separate the code.
When you put the gamelogic in a separate thread, regardless of how many computations you will not freeze/crash/or slowdown your GUI (unless the computation is very intensive and draining the cpu and slowing your entire machine).

 public void run()
    {
        while(true)
        {
            repaint();         
            updateSprites();
            try {
                    Thread.sleep(refreshRate);
            } catch (Exception e) { System.out.println("Exception in run loop: " + e);   }
        }
        
    }
In this example the details/logic of the game-play need not interfere with you GUI. You can use get/set methods for sending and retrieving data between the classes.
  • 0

#8 toto_7

toto_7

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 244 posts

Posted 22 November 2011 - 09:59 AM

Hello fread, thanks for comments. Just would like to inform you that Attachment is not valid (as CodeCall saying) so can't open it
  • 0

"Programming is like **. One mistake and you have to support it for the rest of your life."

-Michael Sinz

#9 fread

fread

    Programming God

  • Senior Member
  • PipPipPipPipPipPip
  • 897 posts
  • Location:Trinidad and Tobago
  • Learning:C, Java, C++, C#, PHP, Python, PL/SQL

Posted 22 November 2011 - 10:39 AM

O Well its a snapshot of Tetris. Just showing the Tetris window and the game-play taking place center towards the center of the frame.
  • 0

#10 toto_7

toto_7

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 244 posts

Posted 22 November 2011 - 03:31 PM

So, to understand what you mean. When the GUI setVisible(true); need to running on a 2nd Thread than the existing?
  • 0

"Programming is like **. One mistake and you have to support it for the rest of your life."

-Michael Sinz

#11 fread

fread

    Programming God

  • Senior Member
  • PipPipPipPipPipPip
  • 897 posts
  • Location:Trinidad and Tobago
  • Learning:C, Java, C++, C#, PHP, Python, PL/SQL

Posted 22 November 2011 - 06:02 PM

Yes. Put you logic code in a separate thread so it does slow you gui.
  • 0

#12 toto_7

toto_7

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 244 posts

Posted 24 November 2011 - 03:53 PM

Hello again,

In my GUI class I have this method

public void Run(){
		new Thread(new Runnable(){
			public void run(){
	               setVisible(true);
            }
        }).start();
	}

But still the chances to Run without stuck or jump steps is not 100%, stuck or jump sometimes
What I'm doing wrong?
  • 0

"Programming is like **. One mistake and you have to support it for the rest of your life."

-Michael Sinz





Also tagged with one or more of these keywords: using thread

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download