Pause on paint

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Shisou
    New Member
    • Jul 2007
    • 52

    Pause on paint

    Okay, so I've done a fair amount of searching and testing on my own so I figure it's time to ask the experts.

    I'm currently building a Java applet. It's purpose is to find a hamiltonian cycle... that part I got working fine... but my problem is this, I want my graph to change colors from black to red as it goes from point to point. I can get them to change colors but i can't seem to get it to update consistently. I've tried adding pauses before calling repaint() after calling repaint() and even in the repaint function but I get relatively the same result.

    The closest I got was putting a pause after each line is drawn on the applet, but this only managed to get me the final result painted slowly.

    here's where changes are made and repaint() is called...

    Code:
    if(eArray[i][vArray[i].edges[j]].visable){
    					eArray[i][vArray[i].edges[j]].col = Color.red;
    				}
    				else{
    					eArray[vArray[i].edges[j]][i].col = Color.red;
    				}
    				vArray[i].visited = 1;
    				steps--;
    				repaint();
    ugh... I don't even know what else to post or say since I've tried every configuration I can think of and the full code is rather lengthy.

    Any help is appreciated
  • r035198x
    MVP
    • Sep 2006
    • 13225

    #2
    You need to read about doing animation using the SwingTimer. Google those things and you should get some useful information.

    Comment

    • Shisou
      New Member
      • Jul 2007
      • 52

      #3
      SwingTimers helped me figure out how to call repaint in a more timely manner. However it would still print out the final result of the graph instead of printing periodic updates. I think this is because while repaint is being called every X milliseconds the rest of the code keeps executing, so in that X seconds the entire path is already calculated. What I would need is a way to pause the rest of the execution while the paint function tries to catch up...

      Thanks for the suggestion btw, swing timers will come in handy in the future so I'm glad I learned about them :)

      Comment

      • r035198x
        MVP
        • Sep 2006
        • 13225

        #4
        Why don't you post what you have now?

        Comment

        • Shisou
          New Member
          • Jul 2007
          • 52

          #5
          Well... the main class is 700+ lines of code and most of it wouldn't help this matter at all.. Here's the main part of it, also I had to fix it up to call repaint() only once because it needed to be submitted today so this is a functioning version without any kind of timers or anything.

          Code:
          else if(e.target == cycleButton){
          			traceMode = true;
          			line = "";
          			trace(0);
          			repaint();
          			return true;
          		}
          this is the button I use to fire trace and repaint. Trace is call recursively as you'll see below.

          Code:
          boolean trace(int i){
          		int j, k;
          		boolean cycle = false;
          		for(j=0;vArray[i].edges[j]!=-1;j++){
          			if(eArray[i][vArray[i].edges[j]] == null){
          				continue;
          			}
          			else if(vArray[i].edges[j] == 0){
          				cycle = true;
          				for(k=0;k<20;k++){
          					if(k == i)
          						continue;
          					else if(vArray[k].visited == 1)
          						continue;
          					else{
          						cycle = false;
          					}
          				}
          				if(cycle){
          					if(eArray[i][vArray[i].edges[j]].visable)
          						eArray[i][vArray[i].edges[j]].col = Color.red;
          					else
          						eArray[vArray[i].edges[j]][i].col = Color.red;
          					return true;
          				}
          			}
          			else if(vArray[vArray[i].edges[j]].visited == 1){
          				continue;
          			}
          			else{
          				if(eArray[i][vArray[i].edges[j]].visable){
          					eArray[i][vArray[i].edges[j]].col = Color.red;
          				}
          				else{
          					eArray[vArray[i].edges[j]][i].col = Color.red;
          				}
          				vArray[i].visited = 1;
          				if(trace(vArray[i].edges[j]))
          					return true;
          				if(eArray[i][vArray[i].edges[j]].visable){
          					eArray[i][vArray[i].edges[j]].col = Color.black;
          				}
          				else{
          					eArray[vArray[i].edges[j]][i].col = Color.black;
          				}
          			}
          		}
          		vArray[i].visited = 0;
          		return false;
          	}
          This function seems to be out of control. If I try using a Thread.sleep() function it sleeps the entire thing including the repaint function (even when repaint is on a timer). I need a way that I can put a break into this function that will hold execution until the repaint function completes.... I just can't figure it out.

          Thanks for any help you can offer... it's not horribly important since the assignment is already turned in... but I'd like to see how this can be done!

          Comment

          • r035198x
            MVP
            • Sep 2006
            • 13225

            #6
            You have to start thinking about the threads in operation. Most likely the function is running on the EDT, right? If you call it in an event handler then it probably is. Now the EDT is also the thread that takes care of updating the interface. So you can't stop your function (sleep) and let the painting continue because you have stopped the thread that is also doing the painting!
            Is that understandable and more importantly is that what you have in your code?

            Comment

            • Shisou
              New Member
              • Jul 2007
              • 52

              #7
              That's absolutely understandable. .. As soon as I started playing with Thread.sleep() I had a feeling I would have to learn about multi-threading :\

              So my first thought is that I will have to either use or create another thread for my paint function so that I can sleep the thread running my trace function and keep the paint going. Is this an accurate assessment of my current predicament?

              Also, do you have a a resource that could help me understand how I can handle threads or have examples of how I can do what I'm trying to do?

              I truly appreciate all of your help! I always learn good things when I ask questions on this forum!

              Comment

              • JosAH
                Recognized Expert MVP
                • Mar 2007
                • 11453

                #8
                You have to do your (time consuming) work in another thread while the EDT thread does its work (painting when needed and firing events when needed). If your, say, actionPerformed () method is called it is called in the EDT. If that method has quite some work to do, migrate that work to another thread. That other thread can sleep all it wants (the EDT is free again to do what it has to do) and that other thread can call the repaint() methods whenever it wants and the EDT will react asap.

                kind regards,

                Jos

                Comment

                • Shisou
                  New Member
                  • Jul 2007
                  • 52

                  #9
                  So... In essense what you're saying is that my trace function should be running on a different thread?

                  How would I be able to do that... When my action performed fires trace() can I specify what thread to run it on?

                  Comment

                  • JosAH
                    Recognized Expert MVP
                    • Mar 2007
                    • 11453

                    #10
                    Originally posted by Shisou
                    So... In essense what you're saying is that my trace function should be running on a different thread?

                    How would I be able to do that... When my action performed fires trace() can I specify what thread to run it on?
                    Yep, that trace() method has to run in its own thread. The following code does just that:

                    Code:
                    new Thread(new Runnable() {
                       public void run() {
                          trace();
                       }
                    }).start();
                    This snippet creates a new thread with a new anonymous Runnable object. This object starts your trace() method in the other thread. This snippet can be the body of an actionPerformed () method.

                    kind regards,

                    Jos

                    Comment

                    • Shisou
                      New Member
                      • Jul 2007
                      • 52

                      #11
                      OOOOOO I love it... it seems to be working beautifully!

                      I had some unexpected side effects and one additional question though...

                      I used this code on my initial call of the trace function... since this is a recursive function will all subsequent calls of trace be run in the new thread or will I have to specify for them to use that thread?

                      Also, Thank you both so much for your time and patience to help myself and other people on these forums... this is such an amazing resource when the rest of the internet fails to help me!

                      Comment

                      • JosAH
                        Recognized Expert MVP
                        • Mar 2007
                        • 11453

                        #12
                        Originally posted by Shisou
                        OOOOOO I love it... it seems to be working beautifully!

                        I had some unexpected side effects and one additional question though...

                        I used this code on my initial call of the trace function... since this is a recursive function will all subsequent calls of trace be run in the new thread or will I have to specify for them to use that thread?
                        If you run that little code snippet outside of your trace() method only one new Thread will be created and your (recursive) thrace() method will run in that single thread, which is, I think, exactly what your want.

                        Originally posted by Shisou
                        Also, Thank you both so much for your time and patience to help myself and other people on these forums... this is such an amazing resource when the rest of the internet fails to help me!
                        Thank you for the compliments,

                        kind regards,

                        Jos

                        Comment

                        • Shisou
                          New Member
                          • Jul 2007
                          • 52

                          #13
                          It's working excellent now... except it won't run on my website, but that's another issue for another thread... thank you again for all your help!

                          Comment

                          Working...