Bookmark and Share
Java Applet Animation Tutorial by Examples

A Java applet is an applet delivered to the users in the form of Java bytecode. Java applets can run in a browser using a Java Virtual Machine (JVM) through the web browser's plugin while other Java applications are executed by the system's Java Runtime Environment. Applets are used to provide interactive features to the web that cannot be provided by HTML alone.

They can capture mouse/keyboard input and on user's action an applet can change the provided graphic content. This makes applets well suitable for visualization.



Please make sure you have at least Java SE Development Kit (JDK) 6 update 10 release on your client machine before proceeding further. Be sure to get the Java SDK and not the JRE (Java Runtime Environment) The Java SDK allows you to compile java programs, the JRE only allows you to run them. 



Not let's start. As usual, you have HelloWorld.

1. Introduction to Java Applet with Hello World

The following example is made simple enough to illustrate the essential use of Java applets through its java.applet package. It uses classes from the Java Abstract Window Toolkit (AWT) for producing output, "Hello, world!". 

There are options other than AWT such as Swing or SWT. 
For more on these options: Comparison AWT, Swing, and SWT.

Though the AWT has been part of Java from the beginning, it was clear that the AWT was not powerful or flexible enough for writing sophisticated applications. Because it seems anyone writing a stand-alone GUI application is using Swing or SWT, Swing/SWT will be my focus for most part of the tutorial.


- HelloWorld.java -

import java.applet.Applet; import java.awt.*; public class HelloWorld extends Applet { // This method is mandatory, but can be empty (i.e., have no actual code). // It is called just after the applet object has been created and before it appears on the screen. // Its purpose is to give the applet a chance to do any necessary initialization. // This method is called by the system, not by your program. public void init() { } // This method is mandatory, but can be empty. public void stop() { } // Print a message on the screen (x=20, y=10). // This paint() method is called by the system when the applet needs to be drawn. public void paint(Graphics g) { //The parameter g, of type Graphics, is provided by the system when it calls the paint() method. g.drawString("Hello, world!", 20,10); } }

Now, using a plain text editor, make the file and name it "HelloWorld.java". The name should be the same as the class name in the code and it's case sensitive.

Let's make a bytecode by compiling it.
Type "javac HelloWorld.java" into command prompt window. Then, we will have a new "HelloWorld.class" file.
Now, it's time to display the applet on the web.

Here is the simple HTML file to make that happen.  
With the opening of the browser, we see Java Applet is working.  "Hello, world!"

<html>
<body>
<applet width=300 height=300
code="HelloWorld.class"> </applet>
</body>
</html>



(Note 1)
  • A Java applet extends the class java.applet.Applet as in this example, or in the case of a Swing applet, javax.swing.JApplet.
  • The resulting HelloWorld.class applet should be installed on the web server and is invoked within an HTML page by using an <APPLET> or a <SCRIPT> tag
  • To minimize download time, applets are usually delivered in a form of compressed zip archive (having jar extension). If all needed classes are placed in compressed archive example.jar, the embedding code would look differently: 
  • <html>
    <body>
    <applet width=300 height=300 code="HelloWorld" archive="HelloWorld.jar"> </applet>
    </body>
    </html> 

(note 2)

If we write the HelloWorld.java using Swing, it looks like this:

The source code is:

import javax.swing.JApplet; import javax.swing.SwingUtilities; import javax.swing.JLabel; //Any applet that contains Swing components must be implemented //with a subclass of JApplet public class HelloWorld extends JApplet { //Called when this applet is loaded into the browser. public void init() { //Execute a job on the event-dispatching thread; creating this applet's GUI. try { // invokeAndWait() is a SwingUtilities method and // make Runnable object to be executed synchronously on the AWT event dispatching thread. // Note that we're not being called from a Swing event handler such as actionPerformed() etc. SwingUtilities.invokeAndWait(new Runnable() { public void run() { JLabel lbl = new JLabel("Hello World"); add(lbl); } }); } catch (Exception e) { System.err.println("createGUI didn't complete successfully"); } } }



2. Drawing - Shapes, Text, and Colors



import java.awt.*; import java.applet.*; public class Shapes extends Applet { Font titleFont = new Font("Serif",Font.BOLD,16); public void init() { setBackground(Color.white); } public void stop() { } public void paint(Graphics g) { g.setFont(titleFont); g.drawString("Shapes and Colors",80,40); // tell g to change the color g.setColor(new Color(255,50,100)); g.setFont(new Font("Arial", Font.ITALIC,30)); g.drawString("Hello World!!", 60, 100); // draw a rectangle (x0,y0,width,height); int x0 = 80, y0 = 150, width = 120, height = 50; g.setColor(Color.blue); g.drawRect(x0,y0,width,height); g.setColor(Color.red); // fill a rectangle with rounded corners g.fillRoundRect(x0+5,y0+5,width-10,height-10,30,30); // draw an oval x0 = 80; y0 = 220; width = 120; height = 50; g.setColor(Color.black); g.drawOval(x0,y0,width,height); g.setColor(new Color(0,255,0)); g.setFont(new Font("Arial", Font.PLAIN,30)); g.drawString("Got it",x0+20,y0+height*3/4); // draw a polygon for the boundary of applet int[] x = {0,290,290,0}; int[] y = {0,0,290,290}; g.setColor(Color.blue); g.drawPolygon(x,y,4); } }




More on Java Graphics Classes http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Graphics.html



3. Mouse Event


Drag the red/orange circle, it will show the mouse position while it's being dragged.

In source code, the overriden method

paintComponent(Graphics g)

is called by the system and we never call this method ourselves. The argument to this method is g which is actual drawing canvas object and we can'g get this by ourselves; it must be handed to us by the system.


-Drag.java-

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Drag extends JApplet implements MouseListener, MouseMotionListener { int mouseX, mouseY; MyPane myPane; public void init() { myPane = new MyPane(); setContentPane(myPane); myPane.setBackground(Color.white); // Register to be notified of mouse event. // The listener interfaces such as MouseListener, // and MouseMotionListener are defined // in the package java.awt.event. // Listening object is the applet itself myPane.addMouseListener(this); myPane.addMouseMotionListener(this); } public class MyPane extends JPanel { // This inner class defines a drawing space // and does the drawing on the space. public void paintComponent(Graphics g) { // The object referenced by the 'g' parameter is actually // an instance of the Graphics2D class. // If you need to use a method from the Graphics2D class, // you can't use this paintComponent parameter('g') // straight from the method. But you can cast it with // a new GraphicsED variable. // Graphics2D g2d = (Graphics2D) g; // Draw the panel and mouse position super.paintComponent(g); // Fills the panel space with background color. g.setColor(Color.blue); int margin = 1; g.drawRect(margin,margin, getSize().width-2*margin,getSize().height-2*margin); Graphics2D g2d = (Graphics2D) g; int r =30; GradientPaint gradient = new GradientPaint(mouseX-r/2,mouseY-r/2,Color.red,mouseX,mouseY,Color.orange); g2d.setPaint(gradient); g.fillOval(mouseX-r/2,mouseY-r/2,r,r); g.setColor(Color.black); g.drawString("(" + mouseX + "," + mouseY + ")", mouseX, mouseY-r/2); } } // JApplet is actually a subclass of Applet. // Though JApplets are in fact Applets, JApplets have a lot of extra structure that plain Applets don't have. // So, when you extend JApplet you should not write a paint() method for it. // Instead you should add a component to the applet to be used for that purpose. //public void paint(Graphics g) { } // MouseListener // In order to detect an event, the program must "listen" for it. public void mouseClicked(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } // MouseMotionListener public void mouseDragged(MouseEvent e) { mouseX = e.getX(); mouseY = e.getY(); myPane.repaint(); } public void mouseMoved(MouseEvent e) { } }


We can simplify above source a little bit using "anonymous event handlers" and "adapter classes". Since a class that implements an interface must provide definitions for all the methods in that interface, even if the definitions are empty. To avoid writing empty method definitions, Java provides adapter classes. An adapter class implements a listener interface by providing empty definitions for all the methods in the interface.

Here is the modified source code using MouseMotionAdapter class:

-DragB.java-

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DragB extends JApplet { int mouseX, mouseY; MyPane myPane; public void init() { myPane = new MyPane(); setContentPane(myPane); myPane.setBackground(Color.white); myPane.addMouseMotionListener(new CircleDragger()); } // Make your drawing widget by making a subcless of JPanel // and override one method, paintComponent(). public class MyPane extends JPanel { // This inner class defines a drawing space // and does the drawing on the space. public void paintComponent(Graphics g) { // Draw the panel and mouse position super.paintComponent(g); // Fills the panel space with background color. g.setColor(Color.blue); int margin = 1; g.drawRect(margin,margin, getSize().width-2*margin,getSize().height-2*margin); Graphics2D g2d = (Graphics2D) g; int r =30; GradientPaint gradient = new GradientPaint(mouseX-r/2,mouseY-r/2,Color.red,mouseX,mouseY,Color.orange); g2d.setPaint(gradient); g.fillOval(mouseX-r/2,mouseY-r/2,r,r); g.setColor(Color.black); g.drawString("(" + mouseX + "," + mouseY + ")", mouseX, mouseY-r/2); } } private class CircleDragger extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { mouseX = e.getX(); mouseY = e.getY(); myPane.repaint(); } } }




Here is another simple mouse event example from Swing buttons.



-ButtonAB.java-

import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ButtonAB extends JApplet implements ActionListener { public void init() { // This method is called by the system before the applet // appears. It is used here to create the buttons and add // them to the "content pane" of the JApplet. The applet // is also registered as an ActionListener for the button. Container contentPane = getContentPane (); contentPane.setLayout(new FlowLayout()); JButton btnA = new JButton("A"); JButton btnB = new JButton("B"); btnA.addActionListener(this); btnB.addActionListener(this); contentPane.add(btnA); contentPane.add(btnB); } public void actionPerformed(ActionEvent event) { // This method is called when an action event occurs. // The buttons respond by showing // an informational dialog box. // Which button? String cmd = event.getActionCommand (); String title = "Message"; // Shown in title bar of dialog box. String message = "Hello from the Swing button "; if ( cmd.equals ("A")){ message += "A."; } else { message += "B."; } JOptionPane.showMessageDialog(null, message, title,JOptionPane.INFORMATION_MESSAGE); } }





The above example for two Swing buttons have some problems in the source code in terms of software design. It's not very OO. We have an eventhandler doing two things which could become hard to maintain and extend later.

The source code has been modified using inner classes of Listener for each button. So, instead of passing this to the button's listener registration method, pass a new instance of the appropriate listener class.

The resulting picture remains the same.


Also worth mentioning is because it has two inner classes, compiler generates two additional classes "myClassName$innerClassA.class" and "myClassName$innerClassB.class" as well as "myClassName.class".

As a result of the inner class, APPLET tag may better be changed. Now we are using another attribute called "archive" for "jar" files:

<applet width=100 height=40 code="ButtonABinner.class" codebase="./JavaAppletClass/" archive="ButtonABinner.jar"> </applet>


Here is the modified source code.

-ButtonABinner.java-

import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ButtonABinner extends JApplet { public void init() { Container contentPane = getContentPane (); contentPane.setLayout(new FlowLayout()); JButton btnA = new JButton("A"); JButton btnB = new JButton("B"); // Instead of passing this to the button's listener // registration method, pass a new instance of the //appropriate listener class //btnA.addActionListener(this); //btnB.addActionListener(this); // ==> btnA.addActionListener(new btnListenerA()); btnB.addActionListener(new btnListenerB()); contentPane.add(btnA); contentPane.add(btnB); } class btnListenerA implements ActionListener { public void actionPerformed(ActionEvent event) { String title = "Message"; String message = "Hello from the Swing button A."; JOptionPane.showMessageDialog(null, message, title, JOptionPane.INFORMATION_MESSAGE); } } class btnListenerB implements ActionListener { public void actionPerformed(ActionEvent event) { String title = "Message"; String message = "Hello from the Swing button B."; JOptionPane.showMessageDialog(null, message, title, JOptionPane.INFORMATION_MESSAGE); } } }






-DrawByDrag.java-


This shows another example of mouse events. It's drawing rectange while the mouse being dragged. It clears the picture before the drawing begins done by

repaint()

in

mousePressed().

So, you can draw only one rectange at a time.


import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DrawByDrag extends JApplet { private int startX, startY, lastX, lastY; MyPane myPane; public void init() { myPane = new MyPane(); setContentPane(myPane); myPane.setBackground(Color.white); myPane.addMouseListener(new RectRecorder()); myPane.addMouseMotionListener(new RectDrawer()); } public class MyPane extends JPanel { // This inner class defines a drawing space // and does the drawing on the space. public void paintComponent(Graphics g) { // Draw the panel and mouse position super.paintComponent(g); // Fills the panel space with background color. g.setColor(Color.blue); int margin = 1; g.drawRect(margin,margin, getSize().width-2*margin,getSize().height-2*margin); g.setColor(Color.blue); drawRectangle(g, startX, startY, lastX, lastY); } } private void drawRectangle(Graphics g, int startX, int startY, int stopX, int stopY ) { int x = Math.min(startX, stopX); int y = Math.min(startY, stopY); int w = Math.abs(startX - stopX); int h = Math.abs(startY - stopY); g.fillRect(x, y, w, h); } private class RectRecorder extends MouseAdapter { public void mousePressed(MouseEvent event) { myPane.repaint(); startX = event.getX(); startY = event.getY(); lastX = startX; lastY = startY; } public void mouseReleased(MouseEvent event) { Graphics g = getGraphics(); g.setColor(Color.blue); drawRectangle(g, startX, startY, lastX, lastY); } } private class RectDrawer extends MouseMotionAdapter { public void mouseDragged(MouseEvent event) { int x = event.getX(); int y = event.getY(); Graphics g = getGraphics(); g.setColor(Color.blue); drawRectangle(g, startX, startY, x, y); lastX = x; lastY = y; } } }





We can modify the code above a little bit using XOR, turn it into a tool for selection box called Rubber Band.

-SelectionRubberBand.java.java-


The changes are:

  • g.setColor() => g.setXORMode()
  • g.fillRect() ==> g.drawRect()

-SelectionRubberBand.java-

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SelectionRubberBand extends JApplet { private int startX, startY, lastX, lastY; MyPane myPane; Boolean init = true; public void init() { myPane = new MyPane(); setContentPane(myPane); myPane.setBackground(Color.white); myPane.addMouseListener(new RectRecorder()); myPane.addMouseMotionListener(new RectDrawer()); } public class MyPane extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.blue); int margin = 1; g.drawRect(margin,margin, getSize().width-2*margin,getSize().height-2*margin); g.setXORMode(Color.green); if(init) { startX = getSize().width*1/4; startY = getSize().height*1/4; lastX = getSize().width*3/4; lastY = getSize().height*3/4; drawRectangle(g, startX, startY, lastX, lastY); } } } private void drawRectangle(Graphics g, int startX, int startY, int stopX, int stopY ) { int x = Math.min(startX, stopX); int y = Math.min(startY, stopY); int w = Math.abs(startX - stopX); int h = Math.abs(startY - stopY); g.drawRect(x, y, w, h); } private class RectRecorder extends MouseAdapter { public void mousePressed(MouseEvent event) { myPane.repaint(); startX = event.getX(); startY = event.getY(); lastX = startX; lastY = startY; init = false; } public void mouseReleased(MouseEvent event) { Graphics g = getGraphics(); g.setXORMode(Color.cyan); drawRectangle(g, startX, startY, lastX, lastY); } } private class RectDrawer extends MouseMotionAdapter { public void mouseDragged(MouseEvent event) { int x = event.getX(); int y = event.getY(); Graphics g = getGraphics(); g.setXORMode(Color.cyan); drawRectangle(g, startX, startY, lastX, lastY); drawRectangle(g, startX, startY, x, y); lastX = x; lastY = y; } } }