Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes

JPWorld Class Reference

The JPWorld class encapsulates artificial world of charged and neutral particles governed by physical laws, i.e. More...

Inheritance diagram for JPWorld:
Inheritance graph
[legend]
Collaboration diagram for JPWorld:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 JPWorld ()
 Creates a new instance of Particle thread tester.
void printUsage ()
 Shows short-cut keys and application usage in log area.
void clearLogArea ()
 Clears log area.
void println (String str)
 Logs a single line of message.
void startTests (float delaySec)
 Starts T1 & T2 tests (delayed for spec.
void onParticleCountChanged (int newParticleCount)
 Adjusts view to current number of particles in the underlying world.
WorldOfParticles.Barrier getBarrier ()
 Gets boundaries of infinite potential barrier keeping particles together.
GraphicsConfiguration getGraphicsConfiguration ()
 Gets the GraphicsConfiguration associated with parent Component.
void createPairOfChargedParticles (int count, double lifeTime)
 Creates pairs of charged particles.
void afterTestsCompleted ()
 Call-back from T3 after all tests have been completed.
void paintComponent (Graphics g)
 Paints the component i.e.
void actionPerformed (ActionEvent ae)
 Handles events from the Swing timer.
void keyPressed (KeyEvent ke)
 Implements KeyListener's key pressed event.
void keyReleased (KeyEvent ke)
 Implements KeyListener's key released event.
void keyTyped (KeyEvent ke)
 Implements KeyListener's key typed event.

Private Member Functions

boolean isFullScreen ()
 Indicates if in fullscreen mode.
void exitFullScreen ()
 Exits full-screen mode.
void toggleFullScreen ()
 Toggles full-screen mode.
void createLogArea ()
 Creates log area for local print-outs.
void changeAnimationResolution (int delta)
 Moves the frame-rate up/down by changing the timer resolution.
void startAnimation (int resolution)
 Starts the animation if not already started, and changes frame-rate.

Private Attributes

WorldOfParticles world = null
 The instance of the world of particles that we are rendering.
Particle hugeMass = null
 Special particle with very huge mass, also called The Big Blue.
final int maxParticlesAllowed = 100
 Creation of new particles should try to keep total amount of particles in the world bellow this limit.
Timer timer = null
 Animation timer used to trigger rendering.
int animationTimerResolution = 5
 Base animation timer resolution.
int backgroundColor = 255
 The background color shade of gray.
volatile boolean annotateForces = true
 Indicates whether to annotate forces acting on particles or not.
JScrollPane logPane = null
 Log pane containing log area.
JTextArea logf = null
 Log (debug, info, error...) messages (instead of System.out).
T3 testerThread = null
 Instance of the T3 class (used to test T1 & T2 classes)

Static Private Attributes

static final long serialVersionUID = 1274716824806299281L
 Implements java.io.Serializable interface.

Detailed Description

The JPWorld class encapsulates artificial world of charged and neutral particles governed by physical laws, i.e.

electrical and gravitational forces as well Newton's law of motions. The motion of each particle is calculated in a separate thread belonging to instance of Particle class. The interacting forces between particles are calculated in single thread for several Particles belonging to the same WorldOfParticles. Instance of the WorldOfParticles is rendered (and animated) inside (as a part of) the JPWorld.

Application's short-cut key are summarized in printUsage().

Author:
Mikica B Kocic

Definition at line 37 of file JPWorld.java.


Constructor & Destructor Documentation

JPWorld.JPWorld (  )

Creates a new instance of Particle thread tester.

Definition at line 100 of file JPWorld.java.

References animationTimerResolution, createLogArea(), startAnimation(), and world.

    {
        this.setLayout( new BorderLayout () );

        /* Create log area used to display textual information to user
         */
        createLogArea ();

        /* Create world of particles...
         */
        world = new WorldOfParticles( this );

        /* Start animation timer...
         */
        startAnimation( animationTimerResolution );
    }

Member Function Documentation

void JPWorld.actionPerformed ( ActionEvent  ae )

Handles events from the Swing timer.

Timer is used to render animation frames at specific animation frame rate.

Definition at line 500 of file JPWorld.java.

References WorldOfParticles.addNewParticle(), backgroundColor, createPairOfChargedParticles(), WorldOfParticles.getParticleCount(), hugeMass, and world.

    {
        /* Do not allow an empty worlds
         */
        if ( world.getParticleCount () == 0 )
        {
            /* Create one huge mass
             */
            hugeMass = world.addNewParticle( 
                    1e12, 0.0, // mass and charge
                    getWidth ()/2 - 200, getHeight () / 2, 25.0, // position and radius
                    Double.POSITIVE_INFINITY // life time
                    ); 

            /* Create one slightly large mass as a satellite
             */
            world.addNewParticle( 
                    1e11, 0.0, // mass and charge
                    getWidth ()/2, getHeight () / 2, 20.0, // position and radius
                    Double.POSITIVE_INFINITY // life time
                    ); 

            /* Create an initial pair of charged particles
             */
            createPairOfChargedParticles( 1, Double.POSITIVE_INFINITY );
        }

        /* Fade-in/out background depending on number of particles
         * (keeping backgroundColor *always* in valid range while changing).
         */
        int alpha = backgroundColor;
        
        if ( world.getParticleCount () > 35 && alpha > 102 ) {
            --alpha;
        }
        else if ( world.getParticleCount () > 55 && alpha > 0 ) {
            --alpha;
        }
        else if ( world.getParticleCount () < 55 && alpha < 102 ) {
            ++alpha;
        }
        else if ( world.getParticleCount () < 20 && alpha < 255 ) {
            ++alpha;
        }

        backgroundColor = alpha < 0 ? 0 : alpha > 255 ? 255 : alpha;
        
        repaint ();
    }
void JPWorld.afterTestsCompleted (  )

Call-back from T3 after all tests have been completed.

Definition at line 431 of file JPWorld.java.

References println(), and testerThread.

Referenced by T3.run().

    {
        synchronized( this )
        {
            testerThread = null; // new tests won't start if testerThread != null

            println( "" );
            println( "Press H for usage..." ); // remind user...
            println( "" );
        }
    }
void JPWorld.changeAnimationResolution ( int  delta ) [private]

Moves the frame-rate up/down by changing the timer resolution.

Parameters:
deltadelta timer resolution in millis

Definition at line 555 of file JPWorld.java.

References animationTimerResolution, and startAnimation().

Referenced by keyPressed().

                                                        {

        int newResolution = animationTimerResolution;
        
        newResolution += delta;

        newResolution = Math.max( newResolution, 0 );
        newResolution = Math.min( newResolution, 500 );
        
        startAnimation( newResolution );
    }
void JPWorld.clearLogArea (  )

Clears log area.

Definition at line 286 of file JPWorld.java.

References logf.

Referenced by printUsage(), and T3.run().

    {
        synchronized( this ) 
        {
            if ( logf != null ) {
                logf.selectAll ();
                logf.replaceSelection( "" );
                logf.setRows( 0 );
            }
        }
    }
void JPWorld.createLogArea (  ) [private]

Creates log area for local print-outs.

Definition at line 252 of file JPWorld.java.

References logf, and logPane.

Referenced by JPWorld().

    {
        synchronized( this )
        {
            if ( logf != null ) {
                return;
            }
                
            /* Log area GUI component
             */
            logf = new JTextArea ();
            
            logf.setLineWrap( true );
            logf.setWrapStyleWord( true );
            logf.setEditable( false );
            logf.setPreferredSize( new Dimension( 250, 0 ) );
            logf.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 14 ) );
            logf.setBackground( new Color( 255, 255, 192 ) );
            logf.setForeground( new Color(   0,   0, 192 ) );
            logf.addKeyListener( this );
            
            /* Log area is scrollable...
             */
            logPane = new JScrollPane( logf );
            logPane.setHorizontalScrollBarPolicy(
                    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
            add( logPane, BorderLayout.EAST );
        }
    }
void JPWorld.createPairOfChargedParticles ( int  count,
double  lifeTime 
)

Creates pairs of charged particles.

Particles are not created after exceeding some limit.

Parameters:
countnumber of particle pairs to create
lifeTimeparticle life-time in seconds

Definition at line 401 of file JPWorld.java.

References WorldOfParticles.addNewParticle(), WorldOfParticles.getParticleCount(), maxParticlesAllowed, and world.

Referenced by actionPerformed(), keyPressed(), T2.run(), and T1.run().

    {
        if ( world.getParticleCount () >= maxParticlesAllowed ) {
            return;
        }

        for ( int i = 0; i < count; ++i )
        {
            double x = ( getWidth  () - 100 ) * Math.random ();
            double y = ( getHeight () - 100 ) * Math.random ();
            
            world.addNewParticle( 1.0, +1.0, // mass and charge
                    x + 100 * Math.random (), // x-pos
                    y + 100 * Math.random (), // y-pos
                    0.0, // radius 0 == random
                    lifeTime + Math.random () * 2 // life time
                    );
            
            world.addNewParticle( 1.0, -1.0, // mass and charge
                    x - 100 * Math.random (),
                    y - 100 * Math.random (),
                    0.0, // radius 0 == random
                    lifeTime + Math.random () * 2 // life time
                    );
        }
    }
void JPWorld.exitFullScreen (  ) [private]

Exits full-screen mode.

Definition at line 184 of file JPWorld.java.

References isFullScreen(), and toggleFullScreen().

Referenced by keyPressed().

    {
        if ( isFullScreen () ) {
            toggleFullScreen ();
        }
    }
WorldOfParticles.Barrier JPWorld.getBarrier (  ) [virtual]

Gets boundaries of infinite potential barrier keeping particles together.

Implements WorldOfParticles.RenderingContext.

Definition at line 374 of file JPWorld.java.

References logPane, and world.

    {
        int logWidth = logPane != null && logPane.isVisible () ? logPane.getWidth () : 0;
        
        return world.new Barrier( 
                15, 15, getWidth () - logWidth - 15, getHeight () - 15 
                ); // component width reduced for the log area and 15 pixels around
    }
GraphicsConfiguration JPWorld.getGraphicsConfiguration (  ) [virtual]

Gets the GraphicsConfiguration associated with parent Component.

Returns:
the GraphicsConfiguration used by parent's Component or null

Implements WorldOfParticles.RenderingContext.

Definition at line 389 of file JPWorld.java.

    {
        return super.getGraphicsConfiguration ();
    }
boolean JPWorld.isFullScreen (  ) [private]

Indicates if in fullscreen mode.

Definition at line 170 of file JPWorld.java.

Referenced by exitFullScreen(), and paintComponent().

    {
        if ( ! ( SwingUtilities.getRoot( this ) instanceof RunStandalone ) ) {
            return false;
        }
        
        RunStandalone jf = (RunStandalone)( SwingUtilities.getRoot( this ) );
        
        return jf.isUndecorated ();
    }
void JPWorld.keyPressed ( KeyEvent  ke )

Implements KeyListener's key pressed event.

Toggles various rendering flags.

Definition at line 591 of file JPWorld.java.

References annotateForces, changeAnimationResolution(), createPairOfChargedParticles(), WorldOfParticles.dump(), exitFullScreen(), hugeMass, WorldOfParticles.incTimeScale(), WorldOfParticles.makeCentripetalVelocities(), Particle.moveParticle(), printUsage(), WorldOfParticles.resetVelocities(), startTests(), toggleFullScreen(), WorldOfParticles.togglePaused(), and world.

                                          {
        
        int keyCode = ke.getKeyCode ();
        
        switch( keyCode )
        {
        case KeyEvent.VK_A:
            /* create a pair of charged particles with life-time 20 ± 10 sec */
            createPairOfChargedParticles( 1, 15.0 + Math.random () * 10.0 );
            break;
            
        case KeyEvent.VK_B:
            /* create five pairs of charged particles with life-time 10 ± 2.5 sec */
            createPairOfChargedParticles( 5, 7.5 + Math.random () * 5.0 );
            break;
            
        case KeyEvent.VK_C:
            createPairOfChargedParticles( 50, 60 + Math.random () * 20.0 );
            break;
            
        case KeyEvent.VK_D:
            world.dump (); // dump to System.out all particle physical props.
            break;

        case KeyEvent.VK_F:
            toggleFullScreen ();
            break;

        case KeyEvent.VK_ESCAPE:
            exitFullScreen ();
            break;
            
        case KeyEvent.VK_H:
            printUsage ();
            break;
            
        case KeyEvent.VK_E:
            world.makeCentripetalVelocities ();
            break;
            
        case KeyEvent.VK_R:
            world.resetVelocities (); // set all velocities to 0
            break;
            
        case KeyEvent.VK_O:
            world.incTimeScale( -0.1 ); // slow-down world's time
            break;
            
        case KeyEvent.VK_P:
            world.incTimeScale( +0.1 ); // speed-up world's time
            break;
            
        case KeyEvent.VK_UP:
            if ( hugeMass != null ) {
                hugeMass.moveParticle( 0, -10 );
            }
            break;
            
        case KeyEvent.VK_DOWN:
            if ( hugeMass != null ) {
                hugeMass.moveParticle( 0, +10 );
            }
            break;
            
        case KeyEvent.VK_LEFT:
            if ( hugeMass != null ) {
                hugeMass.moveParticle( -10, 0 );
            }
            break;
            
        case KeyEvent.VK_RIGHT:
            if ( hugeMass != null ) {
                hugeMass.moveParticle( +10, 0 );
            }
            break;
            
        case KeyEvent.VK_T:
            startTests( 0f );
            break;

        case KeyEvent.VK_N:
            annotateForces = ! annotateForces;
            break;

        case KeyEvent.VK_SPACE:
            world.togglePaused (); // stop/continue physical calculations
            break;

        case KeyEvent.VK_PLUS:
        case KeyEvent.VK_ADD:
            changeAnimationResolution( +5 ); // Slow-down frame rate
            break;

        case KeyEvent.VK_MINUS:
        case KeyEvent.VK_SUBTRACT:
            changeAnimationResolution( -5 ); // Speed-up frame rate
            break;
        }
    }
void JPWorld.keyReleased ( KeyEvent  ke )

Implements KeyListener's key released event.

Definition at line 695 of file JPWorld.java.

    {
        /* unused */
    }
void JPWorld.keyTyped ( KeyEvent  ke )

Implements KeyListener's key typed event.

Definition at line 704 of file JPWorld.java.

    {
        /* unused */
    }
void JPWorld.onParticleCountChanged ( int  newParticleCount ) [virtual]

Adjusts view to current number of particles in the underlying world.

Triggered by WorldOfParticles after some particles are added or removed from the world.

Warning: Method is synchronized (before called) in WorldOfParticles context. To avoid dead-locks, do not use synchronized inside the method.

Parameters:
newParticleCountcurrent particle count in the instance of the WorldOfParticles

Implements WorldOfParticles.RenderingContext.

Definition at line 349 of file JPWorld.java.

References animationTimerResolution, annotateForces, and startAnimation().

    {
        /* Suppress 'force annotations' when particle count exceeds some limit
         * then enable them back when it drops down bellow some (other) limit
         */
        if ( annotateForces && newParticleCount > 20 ) {
            annotateForces = false;
        } else if ( ! annotateForces && newParticleCount < 15 ) {
            annotateForces = true;
        }

        /* Keep CPU happy reducing the frame-rate if there are too many particles
         * to render.
         */
        if ( animationTimerResolution < 20 && newParticleCount > 40 ) {
            startAnimation( 20 );
        } else if ( animationTimerResolution >= 20 && newParticleCount < 40 ) {
            startAnimation( 5 );
        }
    }
void JPWorld.paintComponent ( Graphics  g )

Paints the component i.e.

renders the world of particles

Definition at line 447 of file JPWorld.java.

References animationTimerResolution, annotateForces, backgroundColor, WorldOfParticles.getParticleCount(), WorldOfParticles.getTimeScale(), isFullScreen(), WorldOfParticles.paint(), and world.

    {
        /* Erase the background
         */
        g.setColor( new Color( backgroundColor, backgroundColor, backgroundColor ) );
        g.fillRect( 0, 0, getWidth(), getHeight() );

        /* Engrave background with the information such as particle count,
         * frame-rate and time scale
         */
        {
            int x = 10, y = 0, dy = 20; // position and delta

            g.setColor( Color.BLUE );
            
            g.drawString(
                    String.format( "N = %d particles", world.getParticleCount () ),
                    x, ( y += dy )
                    );
            
            g.drawString(
                    String.format( "Frame-rate: %2$.0f Hz (%1$d ms)", 
                        animationTimerResolution, 1000f / (float)animationTimerResolution
                        ),
                    x, ( y += dy )
                    );
            
            g.drawString(
                    String.format( "Time scale: %.2f", 
                        world.getTimeScale ()
                        ),
                    x, ( y += dy )
                    );

            if ( isFullScreen () ) {
                g.setColor( Color.GRAY );
                
                g.drawString( "Press ESC to exit fullscreen mode...",
                        x, ( y += dy )
                        );
            }
        }

        /* Finally, render instance of the world of particles.
         */
        world.paint( g, annotateForces );
    }
void JPWorld.println ( String  str )

Logs a single line of message.

Parameters:
strcontains message to be shown

Definition at line 303 of file JPWorld.java.

References logf.

Referenced by afterTestsCompleted(), printUsage(), T3.run(), T2.run(), and T1.run().

    {
        synchronized( this )
        {
            System.out.println( str );

            if ( logf == null ) {
                return;
            }

            logf.append( str + "\n" );
            logf.setRows( logf.getRows () + 1 );
            logf.setCaretPosition( logf.getText().length () );
        }
    }
void JPWorld.printUsage (  )

Shows short-cut keys and application usage in log area.

Definition at line 120 of file JPWorld.java.

References clearLogArea(), println(), and testerThread.

Referenced by keyPressed().

    {
        synchronized( this )
        {
            /* Do not print usage while testerThread is running
             */
            if ( testerThread != null ) {
                return;
            }

            clearLogArea ();
            
            boolean hasFrame = ( SwingUtilities.getRoot(this) instanceof RunStandalone );
            
            /* Now, show short-cut keys...
             */
            println( "" );
            println( "        Usage:" );
            println( "------- ----------------------" );
            println( "   A    create one +/- pair" );
            println( "   B    create 5 pairs of +/-" );
            println( "   C    create 50 pairs of +/-" );
            println( "   E    centripetalize vel." );
            
            if ( hasFrame ) {
                println( "   F    toggle fullscreen" );
            }

            println( "   H    help (usage)" );
            println( "   N    annotate forces" );
            println( "   O    slow-down time" );
            println( "   P    speed-up time" );
            println( "   R    reset all velocities" );
            println( "   T    start tests" );
            println( "   +    inc. frame interval" );
            println( "   -    dec. frame interval" );
            println( " space  freeze/unfreeze" );
            println( " arrows move The Big Blue" );
            
            if ( hasFrame ) {
                println( "  esc   exit fullscreen" );
            }
            
            println( "" );
        }
    }
void JPWorld.startAnimation ( int  resolution ) [private]

Starts the animation if not already started, and changes frame-rate.

Parameters:
resolutionframe rate timer resolution in millis

Definition at line 572 of file JPWorld.java.

References animationTimerResolution, and timer.

Referenced by changeAnimationResolution(), JPWorld(), and onParticleCountChanged().

    {
        if ( timer != null ) {
            timer.stop ();
            timer.setDelay( resolution );
        } else {
            timer = new Timer( resolution, this );
        }
        
        animationTimerResolution = resolution;
        
        timer.start ();
    }
void JPWorld.startTests ( float  delaySec )

Starts T1 & T2 tests (delayed for spec.

time) in separate thread.

Parameters:
delaySecdelay in seconds

Definition at line 324 of file JPWorld.java.

References T1.start(), and testerThread.

Referenced by RunAsApplet.init(), keyPressed(), and RunStandalone.RunStandalone().

    {
        synchronized( this )
        {
            if ( testerThread == null )
            {
                testerThread = new T3( this, 5.0f, delaySec );
                testerThread.start ();
            }
        }
    }
void JPWorld.toggleFullScreen (  ) [private]

Toggles full-screen mode.

Definition at line 194 of file JPWorld.java.

References logPane.

Referenced by exitFullScreen(), and keyPressed().

    {
        if ( ! ( SwingUtilities.getRoot( this ) instanceof RunStandalone ) ) {
            return; // not applicable to Applet mode
        }
        
        RunStandalone jf = (RunStandalone)( SwingUtilities.getRoot( this ) );
        
        /* suppress repaints and notifications
         */
        jf.setVisible( false );
        jf.setIgnoreRepaint( true );
        jf.removeNotify ();
        
        /* toggle window title and border
         */
        jf.setUndecorated( ! jf.isUndecorated () );

        /* enable repaints and notifications, then show visible
         */
        jf.addNotify ();
        jf.setIgnoreRepaint( false );
        
        /* rearange components and windows position
         */
        if ( jf.isUndecorated () )
        {
            logPane.setVisible( false );
            
            /* maximize window
             */
            jf.setExtendedState( jf.getExtendedState() | JFrame.MAXIMIZED_BOTH );
        }
        else
        {
            /* Adjust window dimensions not to exceed screen dimensions ...
             */
            Dimension win = new Dimension( 1024, 600 );
            Dimension scsz = Toolkit.getDefaultToolkit().getScreenSize();
            win.width  = Math.min( win.width, scsz.width );
            win.height = Math.min( win.height, scsz.height - 40 );
            jf.setSize( win );
            
            /* ... then center window on the screen.
             */
            jf.setLocation( ( scsz.width - win.width )/2, 
                            ( scsz.height - 40 - win.height )/2 );

            logPane.setVisible( true );
        }

        jf.setVisible( true );
        jf.toFront(); 
    }

Member Data Documentation

Base animation timer resolution.

Definition at line 70 of file JPWorld.java.

Referenced by changeAnimationResolution(), JPWorld(), onParticleCountChanged(), paintComponent(), and startAnimation().

volatile boolean JPWorld.annotateForces = true [private]

Indicates whether to annotate forces acting on particles or not.

Definition at line 80 of file JPWorld.java.

Referenced by keyPressed(), onParticleCountChanged(), and paintComponent().

int JPWorld.backgroundColor = 255 [private]

The background color shade of gray.

Definition at line 75 of file JPWorld.java.

Referenced by actionPerformed(), and paintComponent().

Particle JPWorld.hugeMass = null [private]

Special particle with very huge mass, also called The Big Blue.

It can be moved by the user.

Definition at line 54 of file JPWorld.java.

Referenced by actionPerformed(), and keyPressed().

JTextArea JPWorld.logf = null [private]

Log (debug, info, error...) messages (instead of System.out).

Definition at line 90 of file JPWorld.java.

Referenced by clearLogArea(), createLogArea(), and println().

JScrollPane JPWorld.logPane = null [private]

Log pane containing log area.

Definition at line 85 of file JPWorld.java.

Referenced by createLogArea(), getBarrier(), and toggleFullScreen().

final int JPWorld.maxParticlesAllowed = 100 [private]

Creation of new particles should try to keep total amount of particles in the world bellow this limit.

Definition at line 60 of file JPWorld.java.

Referenced by createPairOfChargedParticles().

final long JPWorld.serialVersionUID = 1274716824806299281L [static, private]

Implements java.io.Serializable interface.

Definition at line 43 of file JPWorld.java.

T3 JPWorld.testerThread = null [private]

Instance of the T3 class (used to test T1 & T2 classes)

Definition at line 95 of file JPWorld.java.

Referenced by afterTestsCompleted(), printUsage(), and startTests().

Timer JPWorld.timer = null [private]

Animation timer used to trigger rendering.

Definition at line 65 of file JPWorld.java.

Referenced by startAnimation().

WorldOfParticles JPWorld.world = null [private]

The instance of the world of particles that we are rendering.

Definition at line 48 of file JPWorld.java.

Referenced by actionPerformed(), createPairOfChargedParticles(), getBarrier(), JPWorld(), keyPressed(), and paintComponent().


The documentation for this class was generated from the following file: