2013-02-23 201 views
3

我一直在嘗試重寫並使用paint組件方法而不是paint方法,因爲我已經看到它在這裏的多個問題中被提出。paintComponent不工作(Java)

我已經看了很多問題,但我仍然無法得到這個工作。我發佈了用於呈現屏幕的原始代碼片段。我在想,擴展JFrame不是正確的方法,而是我需要擴展JPanel,並從那裏使用paint組件。我有另一個對象,我實際上擴展了JPanel,並添加了JFrame(用於渲染)。

下面是我用來渲染的對象,這個方法完全覆蓋了paint方法。

package render; 


import java.util.Arrays; 

import javax.swing.*; 

import java.awt.*; //Graphics, Graphics2D, Image 

import sprites.Picture; 


public class Window extends JFrame{ 
    private static final long serialVersionUID = 1L; 

    public static Picture[] image_list = new Picture[0]; // All the images I want to render 
    private static String win_title = "Window"; // The name of the window 
    private static CustomComponents cc = new CustomComponents(); 


    public Window(){ 
     setTitle(win_title); // set my title 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // close when you hit x button 
     setUndecorated(true); // window has nothing on it 

    } 


    // paints all the images in image list according to their priority 

    public void display(){ 
     add(cc); 
     CustomComponents.updateImageList(image_list); 
     pack(); 

     setMinimumSize(getSize()); 
     setLocationRelativeTo(null); // puts the screen in the middle 
     setResizable(false); // can't resize the window 
     setVisible(true); // to see the window 


    } 



    public double[] getWinSize(){ 
     double[] size = {this.getSize().getWidth(),this.getSize().getWidth()}; 

     return size; 
    } 

    public static void endAll(){ 
     for (Picture i:image_list){ 
      i = null; 
     } 
     image_list = new Picture[0]; 
     CustomComponents.updateImageList(image_list); 
    } 

    // close the window (seen in the game object) 
    public static void close(){ 
     System.exit(0); 
    } 

    // called when adding a new sprite to the image_list array 
    public static void addPicture(Picture element){ 
     Picture[] result = Arrays.copyOf(image_list, image_list.length +1); // does the same thing as the addObject method in objects 
     result[image_list.length] = element; 
     image_list = result; 
     Arrays.sort(image_list); 
     CustomComponents.updateImageList(image_list); 

    } 

    // updates the screen... Just repaints everything 
    public void update() { 
     cc.repaint(); 

    } 

} 


class CustomComponents extends JComponent { 

    private static final long serialVersionUID = 1L; 

    private static Picture[] image_list; 

    public static void updateImageList(Picture[] image_list){ 
     CustomComponents.image_list = image_list; 
    } 

    @Override 
    public Dimension getMinimumSize() { 
     return new Dimension(640,360); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(640,360); 
    } 

    @Override 
    public Dimension getMaximumSize() { 
     return new Dimension(640,360); 
    } 

    @Override 
    public void paintComponent(Graphics graphics) { 
     super.paintComponent(graphics); 
     Graphics2D g2d = (Graphics2D) graphics; 
     for (Picture i:image_list){ 
      if (i.getVisibility()){ 
      g2d.drawImage(i.getPic(), i.getXY()[0], i.getXY()[1], this); 
      } 
     } 
     Toolkit.getDefaultToolkit().sync(); // this is for linux machines 
     graphics.dispose(); // just good programming practice to collect the garbage 
    } 
} 

我會發布實際添加到窗口中的對象,但現在它太複雜了,只有少數事情發生。在構造函數中,我添加上面的JFrame窗口,然後使用計時器調用JFrame對象的更新方法。

如果你們真的需要我可以發佈的代碼,但希望這將足夠。

+0

更改'公共無效paintComponent(圖形圖像) {'to'@Override public void paintComponent(Graphics graphics){'用於在編譯時輸出一些結果。每當重寫方法檢查簽名時使用它,並且該方法存在。 ;) – 2013-02-23 15:45:27

+0

除了其他的建議 - 不要覆蓋update()!也不要調用你的自定義類窗口,這個名稱已經有一個AWT compoent,這會導致混淆。類應該有描述性名稱。 – camickr 2013-02-23 17:13:26

+0

請勿使用graphics.dispose()。該評論與您創建Graphics對象時更相關。在這種情況下,Graphics對象被傳遞給組件,並被其他組件使用。 – camickr 2013-02-23 17:18:32

回答

10
  • 不用油漆

    1. 使用paintComponent()直接向JFrame
    2. 不是好主意,直​​接描繪到JFrameJFrame是不妥當的容器這份工作
    3. 有使用paint()代替paintComponent()代替JFrame,
  • @Override之前你認爲應該重寫父方法,這裏是paintComponent(...)方法。這樣,編譯器會警告你,如果你實際上沒有壓倒你的想法。

  • JComponent/JPanelJFrame

  • 覆蓋getPreferredSizeJComponent/JPanel(你的硬編碼// window size handle),otherwise JComponent/JPanel returns zero dimension,簡單的什麼都不會是可見的creen

+0

對不起,您能否進一步解釋,我無法跟進。 我不明白,「把JComponent/JPanel放到JFrame中」。 我仍然不確定我需要修復的問題:/ – Linkxgl 2013-02-23 15:57:16

+0

您是否嘗試過在我的帖子中鏈接過代碼示例,這裏有關於Oracles教程[Trail:2D Graphics](http://docs.oracle.com)的基本內容/ JavaSE的/教程/ 2D /索引。html) – mKorbel 2013-02-23 16:05:54

+0

@Linkxgl:mKorbel對他的建議是正確的。 1+。如果您無法實施他的建議,請向我們展示您對原始問題底部的編輯嘗試,並讓我們知道此嘗試的任何問題。 – 2013-02-23 16:40:56