I have an applet written using only AWT, that has a customizable bouncing ball moving inside it. All the buttons and scrollbars work if you use them and then press run. But, if you press run first, then the rest of the buttons will not respond. I’m posting the whole program, as I don’t know where the issue is or what I can cut out. I have this compiled in Jcreator and running inside of a 640*480 applet window in a basic HTML page (below the java code).
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Bounce extends Applet implements ActionListener, AdjustmentListener
{
//runtime variables
boolean running = false;
boolean currentlyCircle = true;
boolean showtails = false;
//buttons
Button runbutton = new Button("Run");
Button tailbutton = new Button("Tail");
Button shapebutton = new Button("Square");
Button clearbutton = new Button("Clear");
Button quitbutton = new Button("Quit");
//text
Label speedlabel = new Label("Speed");
Label sizelabel = new Label("Size");
//scrollbars
private final int barHeight = 20;
private final int SLIDER_WIDTH = 10;
private final int MAXSPEED = 110;
private final int MINSPEED = 0;
private final int MAX_SIZE = 110;
private final int MIN_SIZE = 10;
Scrollbar speedbar = new Scrollbar(Scrollbar.HORIZONTAL, MAXSPEED/2, SLIDER_WIDTH, MINSPEED, MAXSPEED);
Scrollbar sizebar = new Scrollbar(Scrollbar.HORIZONTAL, MAX_SIZE/2, SLIDER_WIDTH, MIN_SIZE, MAX_SIZE);
//drawn objs
int size = 50;
private Graphics obj;
Point currentlocation = new Point(100,100);
Point previouslocation;
Point nextlocation;
//boundaries
int bound_x;
int bound_y;
//directions
int dx = 1; //1 = left, -1 = right
int dy = 1; //1 = up, -1 = down
//speed
int speed = speedbar.getValue();
//initialize the applet and draw everything
public void init()
{
Dimension appSize = this.getSize();
bound_x = appSize.width - 100;
bound_y = appSize.height - 232;
double colWeight[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15 cols
double rowWeight[] = {1,1,1,1,1,1,1,1,1,1}; //10 rows
int colWidth[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15 cols
int rowHeight[] = {1,1,1,1,1,1,1,1,1,1}; //10 rows
GridBagConstraints c = new GridBagConstraints();
GridBagLayout gbl = new GridBagLayout();
gbl.rowHeights = rowHeight;
gbl.rowWeights = rowWeight;
gbl.columnWeights = colWeight;
gbl.columnWidths = colWidth;
c.anchor = GridBagConstraints.CENTER;
setBounds(0,0,480,640);
setLayout(new BorderLayout());
Panel p = new Panel();
p.setLayout(gbl);
//speed scrollbar
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 3;
c.gridheight = 1;
c.gridx = 1;
c.gridy = 7;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.speedbar,c);
//run button
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 2;
c.gridheight = 1;
c.gridx = 5;
c.gridy = 7;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.runbutton,c);
//tail button
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 2;
c.gridheight = 1;
c.gridx = 8;
c.gridy = 7;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.tailbutton,c);
//size scrollbar
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 3;
c.gridheight = 1;
c.gridx = 11;
c.gridy = 7;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.sizebar,c);
//speed text label
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 3;
c.gridheight = 1;
c.gridx = 1;
c.gridy = 8;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.speedlabel,c);
//shape button
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 2;
c.gridheight = 1;
c.gridx = 5;
c.gridy = 8;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.shapebutton,c);
//clear button
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 2;
c.gridheight = 1;
c.gridx = 8;
c.gridy = 8;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.clearbutton,c);
//size text label
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 3;
c.gridheight = 1;
c.gridx = 11;
c.gridy = 8;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.sizelabel,c);
//quit button
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 3;
c.gridheight = 1;
c.gridx = 6;
c.gridy = 9;
c.fill= GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.quitbutton,c);
//add to the screen
p.add(this.speedbar);
p.add(this.runbutton);
p.add(this.tailbutton);
p.add(this.sizebar);
p.add(this.speedlabel);
p.add(this.shapebutton);
p.add(this.clearbutton);
p.add(this.sizelabel);
p.add(this.quitbutton);
//add listners
speedbar.addAdjustmentListener(this);
runbutton.addActionListener(this);
tailbutton.addActionListener(this);
sizebar.addAdjustmentListener(this);
shapebutton.addActionListener(this);
clearbutton.addActionListener(this);
quitbutton.addActionListener(this);
//drawing paramaters, draw the first object
obj = getGraphics();
obj.drawOval(100, 100, size, size);
obj.fillOval(100, 100, size, size);
nextlocation = new Point(currentlocation.x+dx, currentlocation.y+dy);
//add the panels
add("South", p);
}
public void run()
{
while (running)
{
if (!showtails)
{
obj.setColor(Color.white);
obj.clearRect(currentlocation.x,currentlocation.y,size+5,size+5);
}
update();
draw(obj);
pause();
move();
}
}
public void update()
{
previouslocation = new Point(currentlocation);
currentlocation = nextlocation;
}
//draw the dot an the next location
public void draw(Graphics obj)
{
obj.setColor(Color.black);
if(currentlyCircle)
{
obj.drawOval(nextlocation.x, nextlocation.y, size, size);
obj.fillOval(nextlocation.x, nextlocation.y, size, size);
}
else
{
obj.drawRect(nextlocation.x, nextlocation.y, size, size);
obj.fillRect(nextlocation.x, nextlocation.y, size, size);
}
}
//wait a period of time, depending on the speed.
public void pause()
{
long waittime = MAXSPEED - speedbar.getValue();
for (long i = 0; i < waittime*100000L; i++) { continue; }
}
public void move()
{
nextlocation = new Point(currentlocation.x+dx, currentlocation.y+dy);
//if it will hit the right or left, flip the x direction and set it
if (nextlocation.x >= bound_x || nextlocation.x <= 0)
{ dx *= -1; }
nextlocation.x += dx;
//if it will hit the top or bottom, flip the y direction and set it
if (nextlocation.y >= bound_y + 100 || nextlocation.y <= 0)
{ dy *= -1; }
nextlocation.y += dy;
}
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if (source == this.runbutton)
{
running = true;
run();
}
else if (source == this.shapebutton)
{
if (currentlyCircle) //if circle, draw it as a rectangle
{
this.shapebutton.setLabel("Square");
currentlyCircle = false;
}
else //if rectangle, draw it as a circle
{
this.shapebutton.setLabel("Circle");
currentlyCircle = true;
}
}
else if (source == this.clearbutton)
{
//clear tail off the screen
obj.clearRect(0,0,bound_x,bound_y);
}
else if (source == this.tailbutton)
{
//toggle showing tails. This is used in run
showtails = true;
}
else if (source == quitbutton)
{
//remove listeners
stop();
}
}
public void adjustmentValueChanged(AdjustmentEvent e)
{
Object source = e.getSource();
//set the new size. If the size is too big its adjusted in draw
if (source == sizebar)
{
size = sizebar.getValue();
}
if (source == speedbar)
{
speed = speedbar.getValue();
}
}
public void stop()
{
this.speedbar.removeAdjustmentListener(this);
this.runbutton.removeActionListener(this);
this.tailbutton.removeActionListener(this);
this.sizebar.removeAdjustmentListener(this);
this.shapebutton.removeActionListener(this);
this.clearbutton.removeActionListener(this);
this.quitbutton.removeActionListener(this);
}
}
HTML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Bounce/title>
<style type="text/css">
body { color: black; background: grey }
</style>
</head>
<body>
<div align="center">
<applet code=Bounce.class width=640 height=480 ></applet>
</div>
</body>
</html>
The
runmethod is your problem. Once this method is executed, you block the Event Dispatching Thread (EDT) from dispatching events, including the all important repaint event…You must NEVER block the EDT.
I would have a read through
Normally, I would suggest the use of a
SwingWorker, but in your case I don’t think it would fit the model, instead, you’re going to have to use aThreadandRunnable.This is going to complicate matters for you, as you should NEVER, EVER update any UI component from any thread other the EDT. For this, you’re going to have to use
SwingUtilities#invokeLaterorSwingUtilities#invokeAndWaitUPDATED
Here’s a little example I put together for another question