[java] Applets aren't working.

Started by
13 comments, last by Tac-Tics 22 years ago
Hi. I''ve been having this problem for a while now and I can''t figure it out.My applet runs fine on appletviewer.exe and the first time on webpages, but when I reload the applet, it screws up really bad. Does anyone know why this happens? If you need any more information about my program, I''ll add it.
Advertisement
what does the browser says on it''s message display at lower left corner?
does it throw any errors?
My hunch tells me that you are spawning a thread from within your applet and when the applet stops this thread is not getting killed eating your JVM resources.

Maybe I am totally wrong!!

Would you elaborate more on the problem.

Regards,
IDispatch
Try changing your init() to start() (I''m not sure if its start() or Start()). Init() is run when the applet is started for the first time, and start() is run when the applet is started for the first time AND every time you go back to your applet in a browser.
OK, I finally got around to testing my program a little more. Sry for the delay. I tried to create a much simpler applet based off of an example in a book I have and it still is acting funny-like. Here''s the two main source files:


  import javax.swing.*;import lifegen.*;publicclass LifeGenAppletextends JApplet{	private Thread gameThread;	private LifeGen game;	public void init ()	{		game = null;		gameThread = null;	}	public void start ()	{		if (gameThread == null)		{			game = new LifeGen(30, this);			gameThread = new Thread(game);			gameThread.start();		}	}	public void stop ()	{		gameThread = null;		game = null;	}}  



  package lifegen;import java.awt.*;import java.awt.geom.*;import javax.swing.*;publicclass LifeGenextends JPanelimplements Runnable{	private JApplet applet;	private GameHandler game;	private Image buffer;	private Graphics bufferGraphics;	private boolean readyToPaint;	private Grid currentGrid;	static	private int cellSize;	static	private int gameSize;	public LifeGen (int size, JApplet applet)	{		this.applet = applet;		readyToPaint = false;		gameSize = size;		Dimension d = applet.getSize();		cellSize = (int) ( (double) (d.width - 10) / (double) (gameSize) );		applet.getContentPane().add(this);	}	public void run ()	{		currentGrid = Grid.getRandGrid(40);//		loadVirusMap();		game = new GameHandler(this);		readyToPaint = true;	}	public void loadVirusMap ()	{		currentGrid = new Grid(getGameSize(), getGameSize() );		int emptyLine = 0;		for (int row = 0; row < getGameSize(); row++)		{			if (emptyLine != 0)			{				for (int col = 1; col < getGameSize(); col += 3)				{					currentGrid.addCell(new Cell(row, col, currentGrid, Color.BLUE) );					try					{						currentGrid.addCell(new Cell(row, col + 1, currentGrid, Color.BLUE) );					}					catch (ArrayIndexOutOfBoundsException arrrg)					{					}				}			}			emptyLine++;			if (emptyLine > 2)				emptyLine = 0;		}		currentGrid.addCell(new Cell(3, 1, currentGrid, Color.RED) );	}	static	public int getCellSize ()	{		return (cellSize);	}	static	public int getGameSize ()	{		return (gameSize);	}	public void stop ()	{		if (game != null)			game.stop();	}	public void paintComponent (Graphics g)	{		if (readyToPaint)		{			Dimension d = applet.getSize();			buffer = applet.createImage(d.height, d.width);			bufferGraphics = buffer.getGraphics();			currentGrid.render(bufferGraphics);			drawGeneration(bufferGraphics);			g.drawImage(buffer, 0, 0, null);		}	}	public void drawGeneration (Graphics g)	{		Graphics2D g2 = (Graphics2D) g;		Rectangle2D box = new Rectangle2D.Double(0, gameSize * cellSize, 120, 20);		g2.setPaint(Color.BLACK);		g2.fill(box);		g2.draw(box);		g2.setPaint(Color.WHITE);		g2.drawString("Generation: " + GameHandler.getGeneration(), 15, gameSize * cellSize + 15);	}	public GameHandler getGameHandler ()	{		return (game);	}	public Grid getCurrentGrid ()	{		return (currentGrid);	}	public void setGrid (Grid g)	{		currentGrid = g;	}}  


It runs fine until you press F5 and reload the browser... Then the new date and old date get stacked up on top of each other and if you reload it over and over, the date becomes unintelligible. Can anyone help me here?

Just as a side note. Earlier, I wasn''t messing with Threads in the program and I just had a stop method that *supposedly* stopped the program by simply rendering all important objects to null, but it didn''t work. Please excuse me for my sloppy, poorly documented and designed code =-)
I couldn''t see in your code how you manage to stop the running thread!!!!

stop() is not being called from anywhere. And btw what is this GameHandler thing... is it another threaded class?
Now that you mention it, the GameHandler class might be very useful to know wouldn''t it =-)


  package lifegen;publicclass GameHandler{	private LifeGen master;	private Grid currentGrid;	static	private int generation;	public GameHandler (LifeGen master)	{		GameHandler.generation = 0;		this.master = master;		currentGrid = master.getCurrentGrid();		run();	}	public void destroy ()	{		master = null;		currentGrid.destroy();	}	public void run ()	{		for (int i = 0; i < 10000; i++)		{			nextGen();			master.repaint();		}	}	public void nextGen ()	{		GameHandler.generation++;		Grid nextGen = new Grid(currentGrid.getSize() );		currentGrid.update(nextGen);		master.setGrid(nextGen);		currentGrid = nextGen;	}	static	public int getGeneration ()	{		return (generation);	}	public void stop ()	{		master = null;	}}  


However, the stop() method is deprecated. Instead, I have made it so the run() method has a limited lifetime, which is the correct way to stop a Thread according to my book.
Part of your problem is that you are creating a new thread and destroying the old thread everytime you go to another browser page. stop() is depracated in Thread, but not in JApplet, so you are correct in the way that you destroy the thread. The problem is when you destroy the thread. The suggested method is to keep a thread alive, even if it is not being used, if it needs to be used later. What you need to do is:

      import javax.swing.*;import lifegen.*;publicclass LifeGenAppletextends JApplet {	private Thread gameThread;	private LifeGen game;	public void init () {		game = null;		gameThread = null;		if (gameThread == null) {			game = new LifeGen(30, this);			gameThread = new Thread(game);			gameThread.start();		}	}	public void start () {		game.go();	}	public void stop () {		game.pause();	}	public void destroy() {		gameThread = null;		game = null;	}}  


Then in your thread(this is trimmed down):


  package lifegen;import java.awt.*;import java.awt.geom.*;import javax.swing.*;public class LifeGenextends JPanel implements Runnable {	boolean go;	public void go() {		go=true;	}	public void pause() {		go=false;	}	public void run() {		while(true) {  //[EDIT] forgot this			if(go) {				do thread stuff			}		}	}}  


I left out synchronization for simplicity, but you might want to sync go()/pause() for thread safety.

This is the the recommended way to handle a thread. You keep the run() going in a continuous loop and pause from the control program with boolean values. This keeps threads from being wasted and gets away from re-initialising a thread every time.

This is where the JApplet.destroy() method comes in handy, because even if the applet is stopped, destroy is called when the browser is closed, so you are guaranteed that your thread will be cleaned up.

---
Make it work.
Make it fast.

"Commmmpuuuuterrrr.." --Scotty Star Trek IV:The Voyage Home

[edited by - CaptainJester on March 27, 2002 1:06:39 PM]

[edited by - CaptainJester on March 27, 2002 1:08:20 PM]
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Well it *seems* to be working now. Thanks for the help. I just have another question. I was fiddling around with a test program and for some reason I can''t get JApplets to respond to keyboard input from a browser (but it works in appletviewer.exe). Why does this happen?


  import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.awt.geom.*;publicclass Boxextends JAppletimplements Runnable{	private Thread appThread;	Shape[] shape;	private boolean running;	private DPanel panel;	public void init ()	{		appThread = new Thread(this);		shape = new Shape[5];		shape[0] = new Rectangle2D.Float(2, 2, 10, 15);		running = false;		panel = new DPanel(this);		appThread.start();	}	public void start ()	{		running = true;		getContentPane().add(panel);	}	public void stop ()	{		running = false;		getContentPane().remove(panel);	}	public void destroy ()	{		appThread = null;		shape = null;	}	public void run ()	{		while (true)		{			if (running)			{				panel.getShapes(shape);				repaint();			}		}	}	public Shape[] getShape ()	{		return (shape);	}	public boolean isRunning ()	{		return (running);	}}class DPanelextends JPanelimplements KeyListener{	private Box applet;	private int count;	private boolean[] keysPressed;	public DPanel (Box applet)	{		this.applet = applet;		count = 0;		addKeyListener(this);		keysPressed = new boolean[150];	}	public void paintComponent (Graphics g)	{		if (applet.isRunning() )		{			super.paintComponent(g);			Graphics2D g2 = (Graphics2D) g;			Dimension d = applet.getSize();			Image buff = this.createImage(d.width, d.height);			Graphics2D buffGraphics = (Graphics2D) buff.getGraphics();			Shape[] shape = applet.getShape();			for (int i = 0; i < shape.length; i++)			{				if (shape[i] != null)					buffGraphics.draw(shape[i] );			}			g2.drawImage(buff, 0, 0, null);		}	}	public boolean isFocusable ()	{		return (true);	}	public void keyPressed (KeyEvent e)	{		int k = e.getKeyCode();		if (! keysPressed[k] )		{			count++;			keysPressed[k] = true;			System.out.println(count);		}	}	public void keyTyped (KeyEvent e)	{	}	public void keyReleased (KeyEvent e)	{		int k = e.getKeyCode();		if (keysPressed[k] )		{			count--;			keysPressed[k] = false;			System.out.println(count);		}	}	public void getShapes (Shape[] shape)	{		if (count == 1)				shape[1] = new Ellipse2D.Double(10, 10, Math.random() * 30, Math.random() * 20);		else		if (count == 2)		{				shape[1] = new Ellipse2D.Double(10, 10, Math.random() * 30, Math.random() * 20);				shape[2] = new Ellipse2D.Double(10, 20, Math.random() * 30, Math.random() * 20);		}	}}  
Just a really quick thought (I didn''t look at the code at all), but have you clicked on the applet to make sure that it has the focus in the browser?

-pirate_dau

This topic is closed to new replies.

Advertisement