<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/*
 *  This program sets up a race between four racers, each trying to fill a
 *  line on the screen with its color before the other racers manage to do so.
 *  This version of the program uses a separate thread for each racer.
 *
 *  Copyright (c) 2010 - Russell C. Bjork
 */
 
import java.awt.*;
import javax.swing.*;

public class ThreadedRacers extends JFrame
{
    /** Main program
     */ 
    public static void main(String [] args) {
        ThreadedRacers race = new ThreadedRacers();
        race.setVisible(true);
        race.runRace();
    }
    
    /** Constructor for the frame that displays the race
     */
    ThreadedRacers() {
        setTitle("Racers");
        getContentPane().setLayout(new GridLayout(0, 1));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(RACER_WIDTH, RACER_COUNT * RACER_HEIGHT);
        
        // Create the racers, add them to the frame
        
        for (int i = 0; i &lt; RACER_COUNT; i ++)
        {
            racer[i] = new Racer(i);
            getContentPane().add(racer[i]);
        }
    }
    
    /** Run the race
     */
    void runRace() {
        Thread [] racerThread = new Thread[RACER_COUNT];
        for (int i = 0; i &lt; RACER_COUNT; i ++)
            racerThread[i] = new Thread(racer[i]);
            
        // Start the racers        
        for (int i = 0; i &lt; RACER_COUNT; i ++)
            racerThread[i].start();

        // Wait for all the racers to finish, then report done        
        for (int i = 0; i &lt; RACER_COUNT; i ++)
            try
            {
                racerThread[i].join();
            }
            catch(InterruptedException e)
            { }            
        System.out.println("All racers are done");
    }

    /** Inner class for the individual racers
     */
    private class Racer extends JComponent implements Runnable
    {
        /** Constructor
         *  @param index the index for this racer
         */
        Racer(int index) {
            this.index = index;
            position = 0;
        }
        
        /** Draw this racer
         *  @param graphics the graphics object
         */
        public void paint(Graphics g) {
            g.setColor(RACER_COLOR[index]);
            g.fillRect(0, 0, 
                  getSize().width * position / 100, 
                  getSize().height);
        }
        
        /** run() method required by Runnable interface.  This code is executed
         *  by the thread associated with this racer 
         */
        public void run() {
            while (position &lt; 100)
            {
                // Kill some time
                
                try
                { 
                    Thread.sleep((int) (200 * Math.random()));
                }
                catch(InterruptedException e)
                { }
                
                position ++;
                repaint();
            }
        }
        
        private int index;
        private int position;
    }

    // Constants to control appearance and number and color of racers
    
    private static final int RACER_WIDTH = 300;
    private static final int RACER_HEIGHT = 50;
    private static final int RACER_COUNT = 4;
    private static final Color [] RACER_COLOR = 
        { Color.red, Color.green, Color.yellow, Color.blue }; 
        
    // The racers
    
    private Racer [] racer = new Racer[RACER_COUNT]; 
}
</pre></body></html>