2013-03-11 22 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