我有一个仅使用AWT编写的applet,它有一个可定制的弹跳球在其中移动。如果您使用它们然后按下运行,所有按钮和滚动条都可以工作。但是,如果先按“运行”,则其余按钮将不响应。我发布了整个程序,因为我不知道问题出在哪里或者我可以删除什么。我在Jcreator中编译并在基本HTML页面(java代码下面)的640 * 480 applet窗口内运行。
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>
答案 0 :(得分:3)
run
方法是您的问题。执行此方法后,您将阻止事件调度线程(EDT)从调度事件,包括所有重要的重绘事件......
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();
}
}
你绝不能阻止EDT。
我会阅读
通常情况下,我会建议使用SwingWorker
,但在您的情况下,我认为它不适合模型,相反,您将不得不使用Thread
和Runnable
这将使您的问题变得复杂,因为您永远不应该从EDT以外的任何线程更新任何UI组件。为此,您必须使用SwingUtilities#invokeLater
或SwingUtilities#invokeAndWait
<强>已更新强>
这是我为另一个问题汇总的一个小例子
public class TestApplet02 extends Applet implements KeyListener, Runnable {
Button options = new Button("Options");
Thread thread = new Thread(this);
int y = 0;
public void init() {
thread.start();
}
@Override
public void start() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setLayout(new BorderLayout());
addKeyListener(TestApplet02.this);
}
});
}
public void paint(Graphics graphics) {
super.paint(graphics);
Graphics2D g2d = (Graphics2D) graphics;
y++;
if (y > getHeight()) {
y = 0;
}
g2d.drawLine(0, y, getWidth(), y);
}
public void run() {
try {
while (true) {
thread.sleep(40);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
repaint();
}
});
}
} catch (InterruptedException exception) {
}
}
public void keyPressed(KeyEvent keyEvent) {
switch (keyEvent.getKeyCode()) {
case KeyEvent.VK_ESCAPE:
// pause game
add(options);
invalidate();
revalidate();
}
}
public void keyReleased(KeyEvent keyEvent) {
}
public void keyTyped(KeyEvent keyEvent) {
}
}