Stack overflow and my dang thread

Okay… Im using the following class (minus the constants string value with the full text) to attempt to create text that displays on the screen in a time delayed way per character(video game wonderment) and in trying to pause it I attempted to create a thread that then caused my top 4 lines to keep creating the class and a stack overflow emerged.

Question… given my code below. What do i need to do to make the thread without stack overflowing and pause the text and end the thread.

After much Googling i am very confused on this subject.

public class TextDelay extends Applet implements Runnable{

	private String 				screenMessage = ""; //stars empty
	private int  				messagePos = 0;
	
	 // Create the object with the run() method
    Runnable runnable = new TextDelay();
    
    // Create the thread supplying it with the runnable object
    Thread thread = new Thread(runnable);
    
    private boolean allDone = false;
	
	 public void run() {
//		  Start the thread
	 	thread.start();
	 	
     }

	
	public void paint ( Graphics g )
    {
		

	    
		
//		update the message
		while (messagePos != ConstantsT.message.length()){
			
			try {
		        long numMillisecondsToSleep = 1000; // 1 seconds
		        Thread.sleep(numMillisecondsToSleep);
		    } catch (InterruptedException e) {
		    }

				screenMessage = screenMessage +  ConstantsT.message.charAt(messagePos);
				messagePos++;
			if (messagePos == ConstantsT.message.length()){
				//thread.allDone = true ;
				break;
			}
		
		}
		 //End of message.
	
            g.setColor   ( Color.blue );
            g.drawString ( screenMessage, 10 , 10 );
    }


	
}

:-\ I am not exactly sure what’s going on in your class! You’ve implemented runnable and your creating new runnables … ???
Here’s a way that you could do it, then you would just have to allocate a long variable per block of text and the rest could be taken care of in your game loop! So the run() method in this example represents the game logic section of your code and the paint() would be the actual rendering part of your code.


import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class TypeWriter extends JFrame implements Runnable
{
	private final String message = "Typewriter-Style Baby!";
	private StringBuffer currMessage = new StringBuffer();
	private int currLetter = 0;
	private Thread thread;
	private long time = 0;
	
	public static void main(String[] args)
	{
		new TypeWriter();
	}

	public TypeWriter()
	{
		addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent we)
			{
				stop();
				System.exit(0);
			}
		});
		setSize(400, 400);
		setVisible(true);
		start();
	}
	
	public void run()
    {
        Thread me = Thread.currentThread();
        while (thread == me)
        {
        	if(time == 0 || System.currentTimeMillis() >= time)
        	{
        		currMessage.append(message.charAt(currLetter));
        		currLetter++;
        		repaint();
        		if(currLetter >= message.length()) stop();
        		time = System.currentTimeMillis() + 500;
        	}
        	else
        	{
        		try
        		{
        			Thread.sleep(100);
        		}
        		catch(InterruptedException ie)
        		{}
        	}
        }
        thread = null;
    }
	
	public void paint(Graphics g)
	{
		g.drawString(currMessage.toString(), 10, 40);
	}
    
    public void start()
    {
       thread = new Thread(this);
       thread.setPriority(Thread.MIN_PRIORITY);
       thread.start();       
    }

    public void stop()
    {
       thread = null;
    }
}

I hope this helps! ;D

I know exactly what is going on. You’re making an infinite loop. How? Read on.

When you call .start() in a Thread, the run() method happens. So if you wanted to make a thread to print out foo, fifty times, you would do this:


private class FooPrint implements Runnable
{
    public void run()
    {
        for (int i = 0; i < 50; i++)
            System.out.println("foo");
    }
}

and you would call it like this:


//Creates the thread, but nothing happens yet.
Thread thread = new Thread(new FooPrint());
//Now you actually will cause the printing by telling
//the thread to start, ie calling its run() method
thread.start();

The way you are doing it creates an infinite loop, because your run method calls the start() method which calls the run() method which calls the start() method etc. etc. etc.

A StackOverflow is generally caused by infinite loop, which is just the case right here.

Instead of saying thread.start() in your run() method, remember that start() always happens before run(), and your run method contols everything… so just change that line to whatever you want to happen in your thread.

Also, your code definitely needs some other work too. You generally would not make a new thread to pause an animation, for example. Rather, you would use a new thread to do something like the opposite – perhaps move an animation at the same time something else is moving it without modifying the main game loop. To pause an animation just pause your game loop, or don’t call the paint() method for that amount of pause time.

Where are you calling paint? The whole structure of your class could use some work. Instead of making the entire class the thread, make a private class that only has the run method in it. This makes everything less confusing and I guarantee you will have less problems.

Hope that all made sense. :slight_smile:

What also catched my attention is that you instantiate an object of the same type while instantiating in:

Runnable runnable = new TextDelay();

So when you instantiate a TextDelay, you instantiate another TextDelay which instantiates another TextDelay, etc etc

Yup after reading this and using my new found debug feature I was creating the class over and over again. This whole program needs to run in an applet so Im not sure on the JFrame code but can see what I can do. This example should get me to where I need to be. Basically Ive set it up so that a string is typed out to the window at your cpus refresh rate. Im trying to slow that down so it does more of a game type feel. Tried a this.wait(1000) and that gave me a lovely other error. So threading is the way to go.

So Ill try to see what I can do about the threading. Any suggestions would be alsome and thanx for the great examples :slight_smile:

Thanx Cborders… I used that example and got it to do what I wanted it to do !!

If you use JApplet instead of JFrame it’s almost exactly the same thing.

;D Sweet! Glad I could help!