1

AWT のみを使用して記述されたアプレットがあり、その中でカスタマイズ可能な跳ねるボールが動きます。すべてのボタンとスクロールバーは、使用してから実行を押すと機能します。ただし、最初に実行を押すと、残りのボタンは反応しません。問題がどこにあるのか、何を切り取ればよいのかわからないため、プログラム全体を投稿します。これを Jcreator でコンパイルし、基本的な HTML ページ (Java コードの下) の 640*480 アプレット ウィンドウ内で実行しています。

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>
4

1 に答える 1

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 は絶対にブロックしないでください。

私は読んでもらいます

通常は a の使用をお勧めしSwingWorkerますが、あなたの場合はモデルに合わないと思います。代わりに、 aThreadとを使用する必要があり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) {
    }
}
于 2012-10-18T02:24:58.890 に答える