Friday, 30 April 2010

Using Thread in Java to Create Animation, Example 5

I said we use the paint() method to have a corner to creat my objects. Further I can have a class for my objects and create images there and bring them on my frame. I need only to pass the graphic of canvas to that class. Then I can even create more than one similar objects on the canvas and put them next together. I can have them resized and rotated and deformed. Now, I use some simple drawings and my aircraft bomber looks more real. I create it in a small sub-class to my canvas. Then I can call it from my paint() method. From this point you can use formalities of object-oriented languages for data encapsulations. But I prefer to experience with animations and put details of software engineering aside until I become fully fluent and in command of more basic details.


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package animation;

/**
 *
 * author Peter Jones
 */
public class Ex5Thread extends javax.swing.JFrame implements java.lang.Runnable {

    /**
     * Creates new form Ex5Thread
     */
    public Ex5Thread() {
        super("Example 5!"); // A title for the frame
        x = X0;
        y = Y0;
        aPanel = new javax.swing.JPanel();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new java.awt.Dimension(840, 400));
        add(aPanel);
        pack();
        start();
    }

    /**
     * Start when browser is loaded or button pushed. *
     */
    public void start() {
        if (fThread == null) {
            fThread = new java.lang.Thread(this);
            fThread.start();
        }
    } // start

    /**
     * The thread loops to draw each frame.*
     */
    public void run() {
        //j=0;
        // Loop through animation frames
        while (fThread != null) {
            // Sleep between frames
            try {
                Thread.sleep(10);
                //build the first image
                java.awt.Graphics gr = getGraphics();
                paint(gr);
                //next, move coordinates
                //such that incoming image won't overlap
                t += 1;
                x = +(int) (V0 * t);
                y = Y0 + (int) (G * t * t / 2);//y-coordinate of bomb
            } catch (InterruptedException e) {
                break;
            } //break stops the loop
            // Now go to other frame
            other();
        }
    }// run ends

    // Your other frame comes here.
    public void other() {
        // check for the end of panel
        isDone();
        // Sleep between frames
        try {
            Thread.sleep(490);
            aPanel.repaint(); // meanwhile repaint the panel.
        } catch (InterruptedException e) {
        }
    }

    /* Boolean allows you to terminate this thread, if you like, and go to other tasks.
     * I used it to provide a flag for counting.
     */
    public boolean isDone() {
        boolean temp = false;
        if (x > 840) {//if reaches end of panel
            temp = true;
            t = 0; //initial t
            x = X0; //initial x
            y = Y0; //initial y
            aPanel.repaint(); //reset the panel
        }
        return temp;
    }

    //Create some graphic
    public void paint(java.awt.Graphics gr) {
        //Next, create object from sub-class!
        new airCraft().paint(gr, x, y, Y0);
        /* gr.setColor(java.awt.Color.green);
         gr.fillOval(x, Y0+10, 100, 20);//fuselage

         gr.setColor(java.awt.Color.red);
         gr.fillArc(x-20, Y0+5, 40, 20, 0, 100);//tail
         gr.fillArc(x+10, Y0+3, 60, 15, 0, 135);//far wing
         gr.fillArc(x+35, Y0+10, 35, 20, 0, -135);//front wing

         gr.setColor(java.awt.Color.gray);
         gr.fillArc(x+55, Y0+10, 40, 10, 0, 100);//cockpit

         gr.setColor(java.awt.Color.red);        
         gr.fillOval(x+30, Y0+y, 10, 5);//bomb*/
    }

    public static void main(String args[]) {
        new Ex5Thread().setVisible(true);
    }

    /* Variables declaration - do not modify
     * For simple GUI
     * For thread animation
     */
    private javax.swing.JPanel aPanel;
    private Thread fThread;

    /* Variables declaration - do not modify
     *
     */
    long t = 0; //seconds

    int x = 20; // X-coordinate of a point
    final int X0 = 20; // pixels

    int y = 50; // Y-coordinate of a point
    final int Y0 = 50; // pixels

    final int V0 = 60; // pixels/second
    final double G = 2.45; //pixels/second/second
    // End of variables declaration

//sub-class creates some graphical object
    class airCraft {

        airCraft() {//Constructor

        }

        protected void paint(java.awt.Graphics gr, int x, int y, int Y) {

            gr.setColor(java.awt.Color.green);
            gr.fillOval(x, Y + 10, 100, 20);//fuselage

            gr.setColor(java.awt.Color.red);
            gr.fillArc(x - 20, Y + 5, 40, 20, 0, 100);//tail
            gr.fillArc(x + 10, Y + 3, 60, 15, 0, 135);//far wing
            gr.fillArc(x + 35, Y + 10, 35, 20, 0, -135);//front wing

            gr.setColor(java.awt.Color.gray);
            gr.fillArc(x + 55, Y + 10, 40, 10, 0, 100);//cockpit

            gr.setColor(java.awt.Color.red);
            gr.fillOval(x + 30, Y + y, 10, 5);//bomb

        }
    }

}

Click here to see the application. If you save the "jar" file in your computer you can use "7z" decompression utility to extract source file and image files.

As you see this is not a smooth animation. To make it smooth, you need to calculate different timings such as effect of a frame on human eyes, rendering a nice artistic image with software, or use pictures instead, using Java Beans to dispatch property changes, using JavaFX and create scenes. When you become familiar with basics that I put here, you can discover further.

Friday, 16 April 2010

Using Thread in Java to Create Animation, Example 4

In the previous example we introduced a simple graphic work. We introduced a paint() method in a cosy corner to create the image we need without interfering with other parts of application. Then we call it back and forth in our thread tick-tacks. To render that graphic to realize the graphical object on our canvas1 we need an instance of java.awt.Graphics which is always present there from deep down the system and easily we catch it from the things that native methods create for us. It is like palette of painters with color pastes on it and different brushes. Once you catch an instance of that you can use it everywhere. The best is to take it from the container that you are working on it. Here I took it from the javax swing panel that I had on my Frame. Once you put the paint() on your canvas to remove it you have to repaint() your canvas; other wise its effect remains there and in the next tick-tack you have still there. In this way you have a moving brush that creates some other type of animation if you are interested. It is like a trajectory you are watching. In this example I have created that effect. Nevertheless, I have to repaint() my panel at each renewal of the thread when the trajectory reaches to the end of canvas, somewhere in isDone() method. You can de-comment and re-comment related instructions to watch its effect. This Blog is the simplest explanation you ever could find anywhere for java threading and painting and animation. Please, have a look at Example 4.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package Forward;

/**
 *
 * author Peter Jones
 */
public class Ex4Thread extends javax.swing.JFrame implements java.lang.Runnable{

    /** Creates new form Ex4Thread */
    public Ex4Thread() {
        super("Example 4!"); // A title for the frame
        T0=System.currentTimeMillis();
        x=X0;
        y=Y0;
        aPanel = new javax.swing.JPanel();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new java.awt.Dimension(350, 120));
        add(aPanel);
        pack();
        start();
    }

    /** Start when browser is loaded or button pushed. **/
    public void start() {
        if (fThread == null){
            fThread = new java.lang.Thread (this);
            fThread.start();
        }
    } // start

    /** The thread loops to draw each frame.**/
    public void run() {
        j=0;
        // Loop through animation frames
        while ( fThread != null){
            // Sleep between frames
            try{
                Thread.sleep (1);
                t=System.currentTimeMillis()-T0;
                t=t/1000; //convert to seconds
                x=(int)(V0*t);
                y=Y0+(int)(G*t*t/2);
                paint();
            }
            catch (InterruptedException e) {break; } //break stops the loop
            // Now go to other frame
            other();
            isDone();
        //if (this.isDone()) fThread = null;
        }
    }// run ends

    // Your other frame comes here.
    public void other(){
        //
        ++j;
        // Sleep between frames
        try{
            Thread.sleep (1);
            //aPanel.repaint(); // meanwhile repaint the panel.
        }
        catch (InterruptedException e) { }
    }

    /* Boolean allows you to terminate this thread, if you like, and go to other tasks.
     * I used it to provide a flag for counting.
     */
    public boolean isDone() {
        boolean temp=false;
        if(j==COUNTS) {
            temp=true;
            j=0;
            T0=System.currentTimeMillis();
            x=X0;
            y=Y0;
            aPanel.repaint();
        }
    return temp;
    }

    //Create some graphic
    public void paint() {

        java.awt.Graphics g=aPanel.getGraphics();
        g.setColor(java.awt.Color.red);
        g.fillOval(x, Y0, 2, 2); //Object one (aircraft)
        g.fillOval(x, y, 2, 2); //Object two (released bomb)
       // g.setColor(java.awt.Color.gray);
        //g.fill3DRect(300, 80, 15, 30, true);

    }

    public static void main(String args[]) {
        new Ex4Thread().setVisible(true);
    }

    /* Variables declaration - do not modify
     * For simple GUI
     * For thread animation
     */
    private javax.swing.JPanel aPanel;
    private Thread fThread;

    /* Variables declaration - do not modify
     *
     */
    int j=0; //counter
    final int COUNTS=3500;

    double t=0; //seconds
    double T0=0; //seconds

    int x=0; // X-coordinate of a point
    final int X0=10; // pixels

    int y=0; // Y-coordinate of a point
    final int Y0=10; // pixels

    final int V0=25; // pixels/second
    final double G=0.98; //pixels/second/second
    // End of variables declaration
}// End of class
Click here to see the application. If you save the "jar" file in your computer you can use "7z" decompression utility to extract source file and image files.
The first trajectory is simple and similar to previous one. It hs a constnt speed of V0=25. Second trajectory follows some rule of mathematics as y=(1/2)g.t2 It is an aircraft bomber with speed of 25 pixels per second and releases a bomb. I assumed the gravity should be one tenth of the earth gravity. It is 0.98 pixels per second per second. x-ccordinate of the bomb remains the same as x-coordiate of the bomber aircraft, that is x=V0*t,  but its y-coordinate changes according to law of gravity.
It is important that you make a formula such that it could be cosistent with the dimensions of canvas. You also should consider for how long your frame remains in the sight. For that it is necessary, too, to know how long the effect of an exposure remains in the eye. It is 20 milli second.

==================================
1. I mean canvas of painting. I do not mean Java AWT Canvas.

Monday, 12 April 2010

Using Thread in Java to Create Animation, Example 3

Now, we are at a point to create animation on our canvas without using an image; doing it just by painting. Still we use the tick-tack technique between run() method and the other() method. Here we have to add a paint() method to create the desired object for us, we put a small red blob, an oval shape on the canvas, moving from left to right. The canvas is a java swing panel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package Forward;
 
/**
 *
 * author Peter Jones
 */
public class Ex3Thread extends javax.swing.JFrame implements java.lang.Runnable{
 
    /** Creates new form Ex3Thread */
    public Ex3Thread() {
        super("Example 3!"); // A title for the frame
        aPanel = new javax.swing.JPanel();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new java.awt.Dimension(200, 100));
        add(aPanel);
        pack();
        start();
    }
 
    /** Start when browser is loaded or button pushed. **/
    public void start() {
        if (fThread == null){
            fThread = new java.lang.Thread (this);
            fThread.start();
        }
    } // start
 
    /** The thread loops to draw each frame.**/
    public void run() {
        j=0;
        // Loop through animation frames
        while ( fThread != null){
            // Sleep between frames
            try{
                Thread.sleep (100);
                x+=3;
                paint();
            }
            catch (InterruptedException e) { }
            // Now go to other frame
            other();
            isDone();
        //if (this.isDone()) fThread = null;
        }
    }// run ends
 
    // Your other frame comes here.
    public void other(){
        //
        ++j;
        // Sleep between frames
        try{
            Thread.sleep (200);
            aPanel.repaint(); // meanwhile repaint the panel.
        }
        catch (InterruptedException e) { }
    }
 
    /* Boolean allows you to terminate this thread, if you like, and go to other tasks.
     * I used it to provide a flag for counting.
     */
    public boolean isDone() {
        boolean temp=false;
        if(j==COUNTS) {
            temp=true;
            j=0;
            x=10;
        }
    return temp;
    }
     
    //Create some graphic
    public void paint() {
         
        java.awt.Graphics g=aPanel.getGraphics();
        g.setColor(java.awt.Color.red);
        g.fillOval(x, 25, 5, 5);
    }
 
    public static void main(String args[]) {
        new Ex3Thread().setVisible(true);
    }
 
/* Variables declaration - do not modify
* For simple GUI
*/
private javax.swing.JPanel aPanel;
 
/* Variables declaration - do not modify
* For thread animation
*/
int j=0; //counter
int x=10; // X-coordinate of a point
Thread fThread;
final int COUNTS=50;
// End of variables declaration
}

Click here to see the application. If you save the "jar" file in your computer you can use "7z" decompression utility to extract source file and image files.

Wednesday, 7 April 2010

Using Thread in Java to Create Animation, Example 2

We could run the thread by tick-tacking between the run() method and an auxiliary other() method, each take the thread to a certain sleep duration. You can test if you can remove the sleep from the other() method. Still you have tick tack but not smooth to create animation. The high of the clock pulse is equal to run() duration say 100 ms but the low (I measured using system time) is 3 to 4 milliseconds. you can add yet another anOther() method and a third image in your resources and get a better effect. you also can play with sleep duration to reach more smoothness in terms of visual subjective effects. you can consider the duration of effect when human eyes switches between two scenes. Now I make a more complex animation. I make these like the old neon lamps rather than using maths calculation and rendering graphics. If I use painting then my attention would be diverted to force correctness of java codes when running in hand in hand with the native operating system. That frequently needs adjustments which is not related to the job of animation. I should be confident that my animations work and encourage me to step forward rather than becoming disappointed. Then I can add other elements to them. This example put pieces of a whole picture consecutively and creates animation similar to the book-flicking through animation that children make using corner of pages of a book.

package Forward;

/**
*
* author Peter Jones
*/
public class Ex2Thread extends javax.swing.JFrame implements java.lang.Runnable {
    /** Creates new form Ex2Thread */
    public Ex2Thread() {
        aPanel = new javax.swing.JPanel();
        aLabel = new javax.swing.JLabel();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new java.awt.Dimension(50, 110));
        add(aPanel);
        aPanel.add(aLabel);
        pack();
        start();
    }
    /** Start when browser is loaded or button pushed. **/
    private void start() {
        if (fThread == null){
            fThread = new java.lang.Thread (this);
            fThread.start();
        }
    } // start
    /** The thread loops to draw each frame.**/
    public void run() {
        j=0;
        // Loop through animation frames
        while ( fThread != null){
            s = mString(j);
            // Sleep 100msecs between frames
            try{
                Thread.sleep (100);
                aLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource(s)));
            }
            catch (InterruptedException e) { }
            // Now go to other frame
            //++j;//
            other();
            isDone();
            //if (this.isDone()) fThread = null;
        }
    }// run ends
    // Your other frame comes here.
    public void other(){
        //
        ++j;
        // Sleep 100msecs between frames
        try{
            Thread.sleep (100);
        }
        catch (InterruptedException e) { }
    }
    // Boolean allows you to terminate this thread, if you like, and go to other tasks.
     // I used it to provide a flag for counting.
     //
    public boolean isDone() {
        boolean temp = false;
        if(j == COUNTS) {
            temp = true;
            j = 0;
        }
    return temp;
    }

    // This method creates strings "Sun0.gif", "Sun1.gif", ..., to "Sun7.gif"
    public String mString(int n){
        String aSt = "";
        aSt = "Sun".concat(java.lang.String.valueOf(n)).concat(".gif");
    return aSt;
    }

    /**
     * Next main
     */
    public static void main(String args[]) {
        new Ex2Thread().setVisible(true);
    }
    // Variables declaration - do not modify
    // For simple GUI
    //
    private javax.swing.JLabel aLabel;
    private javax.swing.JPanel aPanel;
    // Variables declaration - do not modify
    // For thread animation
    int j = 0;
    String s = "";
    Thread fThread;
    final int COUNTS = 8;
    // End of variables declaration
}
Click here to see the application. If you save the "jar" file in your computer you can use "7z" decompression utility to extract source file and image files.
I took small image of "Helios" (Sun personified) in form of an icon. I used the Windows(R) Paint utility and sliced the icon in desired forms. In this way I got eight icons; from "Sun0.gif" to "Sun7.gif". I could make an array of images but I preferred to create a method mString(int n) to fetch the icons one after the other. Then I adjusted my counter from zero to seven to bring images one after another andput them on the java swing label. I could terminate the animation here and go to other jobs by calling isDone() method within the "if" statement and killing the thread; instead of that, I reset my counter back to zero to start it again. I used the isDone() method in a void type fashion. You know in java many boolens can work as void as well without their return value becomes utilized. Hence, I commented the "if" to prevent killing the thread and keep the tick-tack going on and on. If you un-comment this line and comment "j=0; statement" in the isDone() method, then the animation runs only once.
You can also put the "++j" before call to the other() method inside the run() method and then make the call to other() method commented and see the effect. It works but not as smooth as before. Best is to give your clock one tick and one tack; one run() and one other(). Then go and adjust the desired timings inside each state of the run() and the other().

Sunday, 4 April 2010

Using Thread in Java to Create Animation, Example 1

I liked to write a short guide for threads in java. It is because I could not find the existing materials much helpful. None of them dealt with this in a pedagogically clear way. They confuse the reader with materials such as "monitor" and native operating system or by mixing the thread usage with other pieces of a complicate program that deviate the attention to those pieces. Many of them want only to demonstrate an animated program is possible without explaining the thread by itself. Here I use a thread for moving from one image to another image. It is like a "Clock Pulse" or a "tick-tack" When it ticks we have one image when it tacks it shows another image. When the clock pulse is up it shows one image. When the pulse is down it shows the other image. When you use a thread in a java class you should implement java.lang.Runnable() interface. This interface contains the signature for the run() method that you write  for your class. You also need a start method start()  to initiate a thread. As a counterpart  to tick of run() method we need a reset() method for tack of our clock. We need a method that, in case, takes us out of  the tick-tack into a place that we become in control of doing other tasks. This is normally a boolean flag that tests something we predicted in a corner of the tick or in a corner of the tack. I do it simple by counting the tick-tacks and after certain number of loops I stop the animation, through that counter or through the flag. The quartet of start() -  run() - reset() - flag() is all I need. start(): starts tick-tack; run() and reset(): make the tick-tack runs and runs for ever; flag(): stops the tick-tack to go to other jobs if you like to stop it (it inhibits the clock like the hardware inhibit signal). I cannot change names of the run() and start() but I can change names of the other two. I call my reset() as other() to emphasis its job, to prevent confusing it with inhibit. I call my flag() method as isDone() in fashion of java boolean classes. I do not move anything on the screen to demonstrate animation. I only switch between two still pictures to learn how the thread is working between two states. This facilitate my future progress. I had an icon image, "Bella.gif" I used Windows 7 Microsoft Picture Manager and flipped it horizontally and saved the flipped image as "bellb.gif" Then I switched back and forth between these two images. You can see that, tick and tack are both within a never-ending while loop, as far as the thread is not killed; that is, is not null. We call our flag method isDone() to find a way, or rather to arrange, to terminate that loop, for example, if the bell has done fifty tolls. At that time we put the toll counting back to zero for the next round. Here, I embed my code,

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
package Forward;

/**
 *
 * author Peter Jones
 */
// I do not extend java.lang.Thread, I'd rather to implement java.lang.Runnable to be more straight forward
public class Ex1aThread extends javax.swing.JFrame implements java.lang.Runnable{

    /** Creates new "form" Ex1bThread */
    public Ex1aThread() {
        aPanel = new javax.swing.JPanel();
        aLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        setPreferredSize(new java.awt.Dimension(50, 110));
        add(aPanel);
        aPanel.add(aLabel);
        pack();
        // I start a thread just after packing.
        // I could start it from a button or a mouse click
        // or any other event
        start();
    }


    /** Start when browser is loaded or button pushed. **/
    public final void start() {
        // if thread is not active start it
        if (fThread == null){
            fThread = new java.lang.Thread (this);
            fThread.start();
        }
    } // start

    /** The thread loops to draw each frame.**/
    public void run() {
        //  Loop through animation frames
        while ( fThread != null){
            //  Sleep 100msecs between frames
            // Change this value for smoothness
            try{
                Thread.sleep (100);
                // I am counting number of loops
                ++bellTolls;
                // in each loop I "refresh" image icon of the label
                aLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("Bella.gif")));
            }
            catch  (InterruptedException e) { }
            //  Now go to other frame
            other();
            //  I check if bell tolls fifty times I kill fThread by making it null
            if (this.isDone())  fThread = null;
        }
    }// run ends
 
    //  Your other frame comes here.
    public void other(){
        //  Sleep 100msecs between frames
        // Change this value for smoothness
        try{
            Thread.sleep (100);
            // in each loop I "refresh" image icon of the label to other image
            aLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("Bellb.gif")));
        }
        catch  (InterruptedException e) { }

     }

    /*  Boolean allows you to terminate this thread, if you like, and go to other tasks.
     *  I used it to provide a flag for counting. Bell stops after fifty tolls.
     *  The true flag kills the thread, returns the counter to zero to be ready
     */
    public boolean isDone() {
        boolean temp=false;
        //COUNTS is assumed fifty times.
        if(bellTolls==COUNTS) {
            temp=true;
            // I reset the toll counting
            bellTolls=0;
        }
        // returning true kills the fThread
        return temp;
    }

    //
    //  Next main
    //
    public static void main(String args[]) {
        new Ex1aThread().setVisible(true);
    }

    //  Variables declaration - do not modify
    //  For simple GUI
    //
    private javax.swing.JLabel aLabel;
    private javax.swing.JPanel aPanel;

    //  Variables declaration - do not modify
    //  For thread animation
    //
    Thread fThread;
    int bellTolls=0; // this is toll counter
    final int COUNTS=50;
    //  End of variables declaration
}
Click here to see the application (please click on Open/Run and look at top-left corner ). Ifyou save the "jar" file in your computer you can use "7z" decompression utility to extract source file and image file.
I have created a Java Swing Ex1Thread.java class to put my animation over it. That Swing comes in the constructor "public Ex1Thread { bloh, bloh, bloh, ...}" up to the line that we see start(). start() method is invoked after packing the Swing frame by pack() method. Up to this point we do not concentrate on given codes. They are already part of our knowledge. From start() the thread task starts. By putting the start() in the constructor we have started our thread from the point that the class becomes created. (That is the reason for modifying start() as a final or as private method. Had we called it somewhere out of the constructor it simply could override the interface. Ignore these details here.) It is easy to start it from other points in the program, for instance, from action of a button. Other tutorials have done it from a button, but it is confusing since we encounter with event dispatching, then. To prove my control over the threads, in the next example I interrupt between tick-tacks with a third thread such that I have a tick-talk-tack. In this fashion I can manage as many threads in my hand. Here, I embed my code,

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
package Forward;

/**
 *
 * author Peter Jones
 */
public class Ex1bThread extends javax.swing.JFrame implements java.lang.Runnable{

    /** Creates new form Ex1bThread */
    public Ex1bThread() {

        aPanel = new javax.swing.JPanel();
        aLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        setPreferredSize(new java.awt.Dimension(50, 110));
        add(aPanel);
        aPanel.add(aLabel);
        pack();
        start();
    }

    /** Start when browser is loaded or button pushed. **/
    public final void start() {
        if (fThread == null){
            fThread = new java.lang.Thread (this);
            fThread.start();
        }
    } // start

    /** The thread loops to draw each frame.**/
    public void run() {
        //  Loop through animation frames
        while ( fThread != null){
            //  Sleep 100msecs between frames
            // Change its value to adjust its smoothness.
            try{
                Thread.sleep (100);
                ++bellTolls;
                aLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("Bella.gif")));
            }
            catch  (InterruptedException e) { }
            //  Now go to other frame
            other();
            //To appreciate that you can invoke many threads as easy as one
            //create a third thread to interrupt between tick and tack
            anOther();
            if (this.isDone())  fThread = null;
        }
    }// run ends
 
    //  Your other frame comes here.
    public void other(){
        //  Sleep 100msecs between frames
        // Change its value to adjust its smoothness.
        try{
            Thread.sleep (100);
            aLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("Bellb.gif")));
        }
        catch  (InterruptedException e) { }

     }

    //  Your yet another frame comes here.
    // It is t he third thread comes interrupting inthe middle of tick tack
    public void anOther(){
        //  Sleep 100msecs between frames
        // Change its value to adjust its smoothness.
        try{
            Thread.sleep (100);
            aLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("Sun.gif")));
        }
        catch  (InterruptedException e) { }

     }

    /*  Boolean allows you to terminate this thread, if you like, and go to other tasks.
     *  I used it to provide a flag for counting. Bell stops after fifty tolls.
     *  The true flag kills the thread, returns the counter to zero to be ready
     */
    public boolean isDone() {
        boolean temp=false;
        if(bellTolls==COUNTS) {
            temp=true;
            bellTolls=0;
        }
        return temp;
    }
    
    //
    //  Next main
    //
    public static void main(String args[]) {
        new Ex1bThread().setVisible(true);
    }

    //  Variables declaration - do not modify
    //  For simple GUI
    //
    private javax.swing.JLabel aLabel;
    private javax.swing.JPanel aPanel;

    //  Variables declaration - do not modify
    //  For thread animation
    //
    Thread fThread;
    int bellTolls=0;
    final int COUNTS=50;
    //  End of variables declaration

}
Click here to see the application (please click on Open/Run and look at top-left corner ). I put a Helios (personified Sun) between bell tolls. It is done by invoking the method anOther()