Основная анимация не работает - PullRequest
2 голосов
/ 14 февраля 2012

Я учу Java.Это моя первая анимация.Я хочу, чтобы мяч непрерывно двигался вверх и вниз при нажатии кнопки запуска, и он должен STOP при нажатии кнопки остановки.Код, который я написал, перемещает мяч 5 раз (3 раза вниз и 2 раза вверх).Но панель отображает только начальные и конечные позиции, она не отображает промежуточные позиции.Как отображать промежуточные позиции?

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

public class dabble
{
    private boolean z = true;
    private int x=10;
    private int y=10;
    private JFrame frame;
    private JLabel label;
    private mypanel panel;
    private JButton b1;
    private JButton b2;

    public static void main (String[] args)
    {
        dabble dab = new dabble();
        dab.start();
    }

    void start()
    {
        frame = new JFrame();
        label = new JLabel();
        panel = new mypanel();
        b1= new JButton("Start");
        b2= new JButton("Stop");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        b1.addActionListener(new al1());
        b2.addActionListener(new al2());

        frame.getContentPane().add(BorderLayout.NORTH,b1);
        frame.getContentPane().add(BorderLayout.SOUTH,b2);
        frame.getContentPane().add(BorderLayout.CENTER,panel);
        frame.getContentPane().add(BorderLayout.EAST,label);
        frame.setSize(600,600);
        frame.setVisible(true);
    }

    void go()
    {
        for(int i=0;i<5;i++)
        {
            if(z==false)
                break;
            //label.setText("Hi");
            y=510-y;
            panel.repaint();
            try{
                Thread.sleep(500);
                //label.setText("sleep");
            }catch(Exception Ex)
            {
             //label.setText("exp");
            }
        }
    }

    class al1 implements ActionListener{
        public void actionPerformed(ActionEvent event){
            go();
        }
    }

    class al2 implements ActionListener{
        public void actionPerformed(ActionEvent event){
            z=false;
        }
    }

    class mypanel extends JPanel 
    {
        public void paintComponent ( Graphics g)
        {
            g.setColor(Color.white);
            g.fillRect(0,0,this.getWidth(),this.getHeight());
            int red = (int) (Math.random()*255);
            int green = (int) (Math.random()*255);
            int blue = (int) (Math.random()*255);
            Color c1 = new Color(red,green,blue);
            g.setColor(c1);
            g.fillOval(x,y,20,20);
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

Вызов repaint() на самом деле не рисует панель - он просто отмечает, что она будет нарисована позже. И рисование всегда происходит в потоке отправки событий, как и уведомления слушателя событий.

Поскольку go() вызывается в потоке диспетчеризации событий (слушателем действия кнопки), панель не может быть перекрашена во время работы go(). Вы просто ставите в очередь один перекрас, который происходит, как только go() сделано.

Что вы, вероятно, хотите сделать, это использовать javax.swing.Timer, который срабатывает один раз каждые 500 мс, и его действие состоит в том, чтобы переместить шар на один шаг, а затем вызвать repaint().

0 голосов
/ 14 февраля 2012

Хорошо, вы выполняете свой цикл 5 раз (вместо бесконечного цикла). Более того, вы меняете вертикальную позицию с 10 на 500, а затем снова на 10 и т. Д. ... Если вы хотите увидеть промежуточную позицию, вам следует подумать о том, чтобы попросить перекрасить промежуточные позиции, а также указать промежуточные значения y.

Хорошо, выполнение следующих действий решает ваши проблемы, но это определенно плохой дизайн:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class dabble {

    private static final long ANIMATION_DURATION = 5000; // 5 seconds
    private static final int REFRESH_RATE = 10;// 10 times per second
    private boolean incrementing = true;
    private volatile boolean z = true;
    private int x = 10;
    private volatile int y = 10;
    private JFrame frame;
    private JLabel label;
    private mypanel panel;
    private JButton b1;
    private JButton b2;

    public static void main(String[] args) {
        dabble dab = new dabble();
        dab.start();
    }

    void start() {
        frame = new JFrame();
        label = new JLabel();
        panel = new mypanel();
        b1 = new JButton("Start");
        b2 = new JButton("Stop");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        b1.addActionListener(new al1());
        b2.addActionListener(new al2());

        frame.getContentPane().add(BorderLayout.NORTH, b1);
        frame.getContentPane().add(BorderLayout.SOUTH, b2);
        frame.getContentPane().add(BorderLayout.CENTER, panel);
        frame.getContentPane().add(BorderLayout.EAST, label);
        frame.setSize(600, 600);
        frame.setVisible(true);
    }

    void go() {
        new Animation().start();
    }

    class al1 implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            go();
        }
    }

    class al2 implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            z = false;
        }
    }

    class mypanel extends JPanel {
        @Override
        public void paintComponent(Graphics g) {
            g.setColor(Color.white);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            int red = (int) (Math.random() * 255);
            int green = (int) (Math.random() * 255);
            int blue = (int) (Math.random() * 255);
            Color c1 = new Color(red, green, blue);
            g.setColor(c1);
            g.fillOval(x, y, 20, 20);
        }
    }

    class Animation extends Thread {

        private long start;

        @Override
        public void run() {
            start = System.currentTimeMillis();
            while (true) {
                if (!z) {
                    return;
                }
                double progress = (double) (System.currentTimeMillis() - start) / ANIMATION_DURATION;
                System.err.println(progress);
                if (incrementing) {
                    y = (int) (10 + 500 * progress);
                } else {
                    y = (int) (510 - 500 * progress);
                }
                if (progress > 1.0) {
                    start = System.currentTimeMillis();
                    incrementing = !incrementing;
                }

                panel.repaint();
                try {
                    Thread.sleep(1000 / REFRESH_RATE);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...