2012-02-14 4 views
2

Я изучаю 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); 
     } 
    } 
} 
+0

когда-либо считавшийся отступом вашего кода? – aioobe

+2

Вы должны узнать «Как написать код?». Изучите стиль кодирования, соглашение об именах и следуйте им. –

+0

Я сожалею о плохом написании кода, @Ademiban thanks –

ответ

0

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

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

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(); 
       } 
      } 
     } 
    } 
} 
+0

Согласен, что я выполняю его только 5 раз, но он должен отображать эти 5 позиций. Он показывает только конечную позицию. –

+0

Ну, вы вызываете repaint(), который в основном помещает запрос RepaintEvent в очередь AWT-события, так что это будет сделано после того, как вы выпустили текущий поток. Вместо этого вы вызываете сон в очередь AWT-Event, которая предотвращает отправку события (включая событие repaint), поэтому у вас есть одна переименование (события перерисовки объединяются вместе), которая происходит в конце вашего цикла. Вы должны иметь отдельный 'Thread', вызывающий SwingUtilities.invokeLater (новый Runnable() {public void run() {repaint();}});', а затем спящий 500 мс. –

+1

На самом деле, если это отдельный поток, вы можете просто вызвать 'repaint()' непосредственно (это один из немногих методов Swing, который безопасен для использования без EDT). –

2

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

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

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

Смежные вопросы