2013-03-11 160 views
0

所以我正在尝试进入简单的动画和虚拟物理学以及其他方面。我试图让球动画,以便它随着时间的流逝而慢慢增长。我在这里得到的代码与Java For Dummies书中的代码几乎完全相同,除了一些例外:摆脱常量以获取applet的大小(this.setSize(500,500)vs this.setSize(WIDTH,HEIGHT)并在之前声明WIDTH和HEIGHT)。这些变化很简单,不会影响程序。 (我会知道,因为我在学校学习了一门Java课程)。无论如何,我从Applets开始,我无法让程序运行两次迭代。在绘图函数中,我有一个System.out.println(d)来检查椭圆直径增长的次数。然而,我看到的唯一输出是“21”,然后是“22”。该小应用程序继续通过小应用程序查看器运行,但没有其他任何打印,即使它应该继续增长。任何人都知道什么是错的? 作为一个方面说明,我应该提到我正在使用NetBeans 7.2并选择“运行文件”来运行它。JApplet动画未运行

package GraphicsTesting; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.geom.*; 
import java.awt.event.*; 
import java.applet.*; 
import java.util.concurrent.*; 

public class Main extends JApplet 
{ 
    private PaintSurface canvas; 

    @Override 
    public void init() 
    { 
     this.setSize(500,500); 
     canvas = new PaintSurface(); 
     this.add(canvas, BorderLayout.CENTER); 
     ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(3); 
     executor.scheduleAtFixedRate(new AnimationThread(this), 0L, 20L, TimeUnit.MILLISECONDS); 
    } 
} 

class AnimationThread implements Runnable 
{ 
    JApplet c; 

    public AnimationThread(JApplet C) 
    { 
     this.c = c; 
    } 

    public void run() 
    { 
     c.repaint(); 
    } 
} 

class PaintSurface extends JComponent 
{ 
    int d = 20; 
    @Override 
    public void paint(Graphics g) 
    { 
     Graphics2D g2 = (Graphics2D)g; 
     g2.setRenderingHint 
       (RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     d+=1; 
     System.out.println(d);//This is to test 
     Shape ball = new Ellipse2D.Float(200, 200, d, d); 
     g2.setColor(Color.RED); 
     g2.fill(ball); 
    } 
} 

回答

2
/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package javaapplication3; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Ellipse2D; 
import javax.swing.Timer; 
import javax.swing.JApplet; 
import javax.swing.JComponent; 

public class Main extends JApplet { 

    private PaintSurface canvas; 
    private Timer timer; 

    @Override 
    public void init() { 
    this.setSize(500, 500); 
    canvas = new PaintSurface(); 
    this.add(canvas, BorderLayout.CENTER); 
// ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(3); 
// executor.scheduleAtFixedRate(new AnimationThread(this), 0L, 20L, TimeUnit.MILLISECONDS); 
    timer = new Timer(20, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
     canvas.repaint(); 
     } 
    }); 
    timer.start(); 
    } 
} 

class PaintSurface extends JComponent { 

    int d = 20; 

    @Override 
    public void paint(Graphics g) { 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
    d += 1; 
    System.out.println(d);//This is to test 
    Shape ball = new Ellipse2D.Float(0, 0, d, d); 
    g2.setColor(Color.RED); 
    g2.fill(ball); 
    } 
} 

你是在一个线程,是不是Event Dispatch Thread 所以UI不会更新调用重绘()。还有其他方法可以做到这一点,但内部javax.swing.Timer在Event Dispatch Thread内调用actionPerformed方法,以便更新UI。

UPDATE:你可以看到使用Java在webstart行动的小程序:https://tetris-battle-bot.googlecode.com/files/launch.jnlp

+0

我还补充说,更新'paint'方法内的游戏状态是一个非常糟糕的主意,因为'paint'方法可以独立更新。此外,调用'super.paint'将是明智的,实际上,OP应该鼓励不要从顶级容器扩展并使用类似'JPanel' ....或类似的东西;) – MadProgrammer 2013-03-11 06:28:46

+0

感谢指出这一点。 :D – 2013-03-11 07:11:16

0

以上回答不工作。然而,看着你的原始代码,有一点小小的误解,看起来,你们都没有发现。在动画线程的构造函数中,您将JApplet C作为参数而不是JApplet c。为了澄清,你意外地大写了cC的资本化导致您设置基本上将其分配给自己的this.c = c。根本不需要重写整个代码。

+0

它的工作。您可以使用java webstart和这个jnlp文件来查看applet https://tetris-battle-bot.googlecode.com/files/launch.jnlp 我使用Netbeans构建。 – 2013-03-14 10:49:52