Dylan Siegler Dylan Siegler - 24 days ago 12
Java Question

Why this Simple Loop is Causing Problematic Behavior of my JFrame

I am doing an assignment from the Java Exposure textbook, which was written in 2007. This book includes some code that I usually update to use some of the more recent features (just basic stuff). However, in this one I am running into a problem. All I tried to do is replace the

show
with
setVisible(true)
and change the
Frame
to a
JFrame
and add a
gfx.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
. However, I noticed that this wouldn't actually cause the window to close. If I clicked many times, maybe 1/30 tries it would close. If I reduced the delay from 10 to 1, it usually closed within 2 tries. This of course led me to believe that the
delay
method is causing this erratic behavior. I tried
Thread.sleep
, but of course that didn't work. Is there any simply way to get this code so that the frame will close when I hit the close button? If there isn't, what would be the less simple way of doing it?

Here is the code:

// Lab30st.java
// The Screen Saver Program
// Student Version


import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.JOptionPane;


public class Lab30st
{
public static void main(String args[])
{
GfxApp gfx = new GfxApp();
gfx.setSize(800,600);
gfx.addWindowListener(new WindowAdapter() {public void
windowClosing(WindowEvent e) {System.exit(0);}});
gfx.show();
}
}


class GfxApp extends Frame
{

private int circleCount, circleSize;

public GfxApp()
{
circleCount = 50;
circleSize = 30;
}


class Coord
{
private int xPos;
private int yPos;

public Coord(int x, int y)
{
xPos = x;
yPos = y;
}
}

public void paint(Graphics g)
{
int incX = 5;
int incY = 5;
int diameter = 30;
int timeDelay = 10;
Circle c = new Circle(g,diameter,incX,incY,timeDelay);
for (int k = 1; k <= 2000; k++)
{
c.drawCircle(g);
c.hitEdge();
}

}
}



class Circle
{
private int tlX; // top-left X coordinate
private int tlY; // top-left Y coordinate
private int incX; // increment movement of X coordinate
private int incY; // increment movement of Y coordinate
private boolean addX; // flag to determine add/subtract of increment for X
private boolean addY; // flag to determine add/subtract of increment for Y
private int size; // diameter of the circle
private int timeDelay; // time delay until next circle is drawn



public Circle(Graphics g, int s, int x, int y, int td)
{
incX = x;
incY = y;
size = s;
addX = true;
addY = false;
tlX = 400;
tlY = 300;
timeDelay = td;
}

public void delay(int n)
{
long startDelay = System.currentTimeMillis();
long endDelay = 0;
while (endDelay - startDelay < n)
endDelay = System.currentTimeMillis();
}

public void drawCircle(Graphics g)
{
g.setColor(Color.blue);
g.drawOval(tlX,tlY,size,size);
delay(timeDelay);
if (addX)
tlX+=incX;
else
tlX-=incX;
if (addY)
tlY+=incY;
else
tlY-=incY;
}


public void newData()
{
incX = (int) Math.round(Math.random() * 7 + 5);
incY = (int) Math.round(Math.random() * 7 + 5);
}

public void hitEdge()
{
boolean flag = false;
if (tlX < incX)
{
addX = true;
flag = true;
}
if (tlX > 800 - (30 + incX))
{
addX = false;
flag = true;
}
if (tlY < incY + 30) // The +30 is due to the fact that the title bar covers the top 30 pixels of the window
{
addY = true;
flag = true;
}
if (tlY > 600 - (30 + incY))
{
addY = false;
flag = true;
}
if (flag)
newData();
}

}

Answer

You are "freezing" the Event Dispatch Thread with

public void delay(int n)
    {
        long startDelay = System.currentTimeMillis();
        long endDelay = 0;
        while (endDelay - startDelay < n)
            endDelay = System.currentTimeMillis();  
    }

This means that all the other stuff that is trying to happen (like closing the window) has to wait until the thread comes out of the "sleep". basically you shouldn't be doing the delay in the EDT, it should be on a different thread and then ask the EDT thread to update.

Your "busy wait" delay may cause other problems too. You can improve the behavior by using Thread.sleep()

See Java Event-Dispatching Thread explanation

Comments