Java: The Document Class

all things must have a beginning

Well, they are not called Document Classes in Java. They are more like the Application class in Flex. Usually they will determine the type of application you have, if windowed, applet, midlet, bean... Since this is a windowed application, the class must extend JFrame. It means window.

public class Atlantis extends JFrame implements WindowListener {

The class then inherits from JFrame and uses the WindowListener interface, for window events.

//this method starts things rolling
public static void main(String args[]) {
	new Atlantis();
}

This is the entry point of a Java application. It is always a public static method, always called main, it never returns anything, and it always receives an array of Strings as a parameter. Within it, you will usually create an instance of the application.

The method can be very useful when testing the application, as you can pass it values from a console (like command prompt in windows.)

The Constructor

public Atlantis () {
	super ("Atlantis");
	_gameStage = GameStage.getInstance();
	
	this.getContentPane().add(_gameStage, "Center");
	
	addWindowListener( this );
	pack();
	setResizable(false);
	setVisible(true);
	
	Sprites sprites = Sprites.getInstance();
	GameController.getInstance().init();
}

Here I take care of the process of creating a window. Most of the methods here are inherited from JFrame. I pass to the JFrame constructor the title of the window: Atlantis. Then I create the GameStage and I add it to the window.

The getContentPane method is similar to the idea of contentGroup in Flex. Even the positioning logic is similar to the way it is done in Flex. No surprises there, as Flex was probably meant to be a way to attract Java developers to the Flash world.

I add the window events, passing the instance of Atlantis as the listener. I call the method pack, which basically means, put things in place before I make this thing visible.

Here I create the one instance of Sprites because in the Java version the PNG will not be embeded, but must be loaded locally, and I want to do that as soon as I can. And then I start the game calling init on GameController. Just as I did in the Flash version.

The Window Events

And now the first introduction to the event model in Java. There are basically two ways to add built in events to your objects. And the first way is: You must implement the listener interface you want to use (more on the second way later.)

The problem with this way is that you must account for every method in that interface. So all the events in WindowListener must be taken into account. Which is the reason I ended up with a lot of empty methods:

public void windowClosed(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}

When all I needed is the event for window closing.

public void windowClosing(WindowEvent e) {
	_gameStage.stopGame();
}

Again, I didn't have to worry about this in Flash. But think of it as a good thing. You have far more control over the Virtual Machine as you have over the Flash player. Of course, as Uncle Ben used to say, with great power comes great responsibiliy.

The First Words on Threads

So you should know that a Thread is generally a Task done parallel to your application. It doesn't necessarily mean it is done at the same time, but nowadays with the dual core revolution and multiple processors being as common as Ass, it is more probable for that to be the case.

When you create a thread, you can make it do anything, and that thing will be done almost as a separate application.

In Flash you have one thread for your application. So it works like this: do this, then do this, then do this, then do this, then do this... There is space for synchronism problems as I showed you before, but nothing major.

In Java you can build things the same way, with one thread. Incidently that one thread is called the main thread and it's started when that very same public static main method is called.

Also, I must point out that events in Java are handled in their own thread. So technically, it is pretty much impossible to use only one thread, you have the Main one and the Event one, running separately.

Running threads is a lot like the dude rotating a bunch of plates on sticks. And he has to run between the sticks and keep rotating the plates and he goes almost crazy with it and we laugh, and laugh.

If you have multiple processors you will have more than one dude helping with the plates. Otherwise you will have one fast dude, alternating between plates.

With threads the processing of the application is more like: Main Thread (do this, then do this, then do this, Thread 2: Hey sorry to butt in, but I finished the task you told me to and here is the result, cheerio!, then do this, then... Thread 3: Hello, there, I'm done too, see ya ... do this, then do ... Thread 4: done, gotta go... this.) Synchronism is everything here. Every time you run that application the Threads might come and go at different points in the life cycle of your application, and you will never control the order they come in. And this is the reason you MUST think of a thread as a separate entity. The better you separate them from resources in your main thread, the better your life as a Java developer will be.

For Game development, Threads are important because it is very common to create the main loop within a thread.

But the reason I wanted to do a first introduction to Threads here is to point out to you that the MAIN thread is created here.

Syntanx

To declare a variable, instead of:

private var myVariable:SomeObject

use:

private SomeObject myVariable;

To declare a method, instead of:

public function getMeThePresident (phoneNumber:Number):ThePresident {}

use:

public ThePresident getMeThePresident (Number phoneNumber) {}

The Atlantis Class

import java.awt.event.*;

import javax.swing.JFrame;

import atlantis.GameController;
import atlantis.GameStage;
import atlantis.elements.Sprites;

public class Atlantis extends JFrame implements WindowListener {

	private GameStage _gameStage;
	
	public Atlantis () {
		super ("Atlantis");
		_gameStage = GameStage.getInstance();
		
		this.getContentPane().add(_gameStage, "Center");
		
		addWindowListener( this );
		pack();
		setResizable(false);
		setVisible(true);
		
		Sprites sprites = Sprites.getInstance();
		GameController.getInstance().init();
	}
	
	
	public void windowClosing(WindowEvent e) {
		_gameStage.stopGame();
	}
	
	//unless using an adapter, you must declare all unused events (i don't like adapters)
	public void windowClosed(WindowEvent e) {}
	public void windowOpened(WindowEvent e) {}
	public void windowActivated(WindowEvent e) {}
	public void windowDeactivated(WindowEvent e) {}
	public void windowDeiconified(WindowEvent e) {}
	public void windowIconified(WindowEvent e) {}
	
	
	//this method starts things rolling
	public static void main(String args[]) {
		new Atlantis();
	}
}