2015-01-05 40 views
0

我創建了一個Java應用程序,我使用JComponent類來繪製。 我有一個repaint()方法不啓動paintComponent()的問題。 這可能是什麼原因?重繪()不調用JComponent類中的paintComponent()

代碼:

JComponent類:

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

import javax.swing.JComponent; 
import javax.swing.Timer; 

public class Display extends JComponent implements ActionListener{ 

    private final static int Width = 400; 
    private final static int Height = 600; 
    private long period; 
    private Timer timer; 

    private Background background; 

    private boolean isRunning = false; 

    public Display(long period) { 
     this.period = period; 
     setSize(Width, Height); 
     prepeareUi(); 
     setOpaque(false); 
    } 

    public void addNotify() { 
     if(!isRunning) { 
      timer = new Timer((int)period, this); 
      timer.start(); 
      isRunning = true; 
     } 
    } 

    public void stop() { 
     if(isRunning) 
      isRunning = false; 
    } 

    private void prepeareUi() { 
     background = new Background(Width, Height); 
    } 

    public void paintComponent(Graphics g) { 
     g.setColor(Color.WHITE); 
     g.fillRect(0, 0, Width, Height); 
     background.draw(g); 
    } 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     if(isRunning) { 
      background.update(); 
      repaint(); 
      return; 
     } 

     System.exit(0); 

    } 

} 

Frame類:

import javax.swing.JFrame; 

public class Frame extends JFrame { 

    private static final int DEFAULTFPS = 20; 

    public Frame(long period) { 
     prepearUI(period); 
    } 

    private void prepearUI(long period) { 
     Display d = new Display(period); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     add(d); 
     pack(); 
     setResizable(false); 
     setVisible(true); 
    } 

    public static void main(String[]args) { 
     String fpsS = null; 
     if(args.length==1) 
      fpsS = args[0]; 

     int fps = (fpsS != null) ? Integer.parseInt(fpsS) : DEFAULTFPS; 
     long period = (long) (1000.0/fps); //In Ms! 

     Frame f = new Frame(period); 
    } 

} 

背景類

import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 

import javax.imageio.ImageIO; 


public class Background { 

    private int ParentWidth; 
    private int ParentHeight; 

    private int width; 
    private int height; 

    private BufferedImage image; 

    private float x = 0; 
    private float y = 0; 

    private final static float ANIMATIONSPEED = 1F; 
    private final static int ANIMATION_RIGHT = 0; 
    private final static int ANIMATION_LEFT = 1; 

    private int animationway = 1; 

    public Background(int W, int H) { 
     ParentWidth = W; 
     ParentHeight = H; 
     prepeareImage(); 
    } 

    private void prepeareImage() { 
     width = 0; height = 0; 
     try { 
      image = ImageIO.read(getClass().getResource("UI\\background.png")); 
      width = image.getWidth(null); 
      height = image.getHeight(null); 
     } catch (IOException e) { 
      System.err.println("Background.png not found!"); 
     } 
    } 

    public void update() { 
     if(animationway == ANIMATION_RIGHT) { 
      x += ANIMATIONSPEED; 
      if(x>=0F) { 
       animationway = ANIMATION_LEFT; 
      } 
     } 

     if(animationway == ANIMATION_LEFT) { 
      x -= ANIMATIONSPEED; 
      if(x<=width/-1+ParentWidth) { 
       animationway = ANIMATION_RIGHT; 
      } 
     } 
    } 

    public void draw(Graphics g) { 
     g.drawImage(image, (int) x, (int) y, null); 
    } 

} 
+0

在setSize上使用getPreferredSize;請在執行自定義繪畫之前調用super.paintComponent – MadProgrammer

回答

4

的問題是,你的覆蓋沒有調用父項的實現。這打破了很多東西,重新打包通知可能就是其中之一。您可以通過將super.addNotify();添加到您的實施中來解決此問題。我不會碰addNotify。不要重寫它。在構造函數中初始化計時器或添加父母可以調用以啓動計時器的方法。您已經有方法stop(),所以只需創建方法start()

JComponent.addNotify()文檔指出:

通知此組件它現在已有了一個父組件。當調用此 方法時,父組件的鏈將與KeyboardAction事件偵聽器一起設置爲 。該方法在內部由工具包 調用,不應由程序直接調用。

編輯:

爲了避免損壞油漆鏈確保您撥打super.paintComponent()在實施paintComponent()。詳情請參閱Performing Custom PaintingPainting in AWT and Swing

+1

您是否可以通過不致電super.paintComponent添加關於打破繪畫鏈的評論 – MadProgrammer

+0

@MadProgrammer yes,done,thanks! :) – tenorsax

+1

好的!沒想到那個!非常感謝:) – user3641882

相關問題