java - 小程序运行时按钮和滚动条不响应

标签 java button applet awt

我有一个仅使用 AWT 编写的小程序,其中有一个可自定义的弹跳球在其中移动。如果您使用它们然后按运行,所有按钮和滚动条都可以使用。但是,如果您先按运行,则其余按钮将不会响应。我正在发布整个程序,因为我不知道问题出在哪里或我可以删掉什么。我在 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>

最佳答案

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 ,但在您的情况下,我认为它不适合该模型,相反,您将不得不使用 ThreadRunnable .

这会让你的事情变得复杂,因为你永远不应该从 EDT 以外的任何线程更新任何 UI 组件。为此,您将不得不使用 SwingUtilities#invokeLaterSwingUtilities#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) {
    }
}

关于java - 小程序运行时按钮和滚动条不响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12946063/

相关文章:

java - NoClassDefFoundError : Could not initialize class com. sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl

java - 具有初始顶点的 JGraphx 图形编辑器

java - android studio 调用按钮

Java Applet - 签名 applet 类而不是 applet jar

java - 一个小程序试图从哪里加载一个类?

java - 在某些情况下,将 Long 乘以 float 会导致错误

java - Java 编译器可以重新排序函数调用吗?

css 样式 <button> 显示灰色背景

Android非矩形按钮,如何处理?

java - 使用 Java Applet 记住智能卡 PIN 码以访问 keystore