2013-10-02 144 views
1

我正在學習一個教程,輸出窗口打印出「Hello World!」那裏。我的問題是,paint()方法不是從任何地方調用,那麼它如何打印「Hello World!」 ?爲什麼會出現這種輸出?

這裏是代碼..

package javagame; 

import java.awt.Graphics; 

import javax.swing.JFrame; 


public class JavaGame extends JFrame{ 

    public JavaGame(){ 

     setTitle("sadid java game");  
     setSize(500, 500); 
     setResizable(false); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 

    public void paint(Graphics g){ 
     g.drawString("Hello world !!!!",30,30); 
    } 

    public static void main(String[] args) { 
     new JavaGame(); 

    } 

} 

在教程它通常打印與窗口的 「Hello World!」但是當我運行相同的代碼時,出現這個可怕的output。這種輸出如何出現,爲什麼?代碼中有沒有問題..?

+5

請在代碼塊中包含代碼,而不是屏幕截圖。 – kiheru

+0

我計劃發佈代碼。但我不知道我是如何跳過它的......爲此而努力...... @kiheru –

回答

5

這是一個Swing GUI,發佈的類擴展了JFrame並覆蓋了paint方法(你不應該這樣做)。

要回答你的問題,所有Swing組件的paint方法重寫會在組件被呈現時由JVM自動調用。組件在應用程序啓動時顯示,組件是否可見,何時調整大小以及操作系統是否感覺組件的窗口「髒」並需要重新繪製時呈現。

如果您通過建議通過調用組件上或其層次結構上的任何容器上的任何容器來重新繪製組件,也可以繪製組件。請注意,我說「建議」,因爲您只能要求重繪管理器繪製組件,但通常不會「請求」它,所以您可以讓重繪管理器選擇不重繪區域,如果重繪請求堆棧向上。

所以這意味着繪畫方法永遠不會受到您的直接控制,並且可以多次或不頻繁地調用。

的原因,該代碼是不好的代碼遵循的是:

  • 他們的油漆例子並不調用super.paint(g)方法,所以你要覆蓋一個JFrame的paint方法沒有告訴它做它正常的繪畫。
  • paint方法負責繪製組件的子元素和邊框,對於JFrame這是非常重要的。通過不調用超級方法,您可能會肆意搞亂JFrame的這些部分。
  • 默認情況下,paint方法不會執行雙緩衝,並且如果您嘗試使用它進行動畫,那麼除非您手動使用雙緩衝區,否則將保證會有波濤洶涌的動畫。

所以總和,不重寫一個JFrame的paint方法,除非你很清楚你在做什麼(這視頻的作者是),瞭解所涉及的風險。要正確繪製,請查看官方Painting in Swing Tutorials,並按照其示例進行操作。有關更詳細的解釋,請閱讀Painting in AWT and Swing

什麼樣的教程是試圖展示將是一個更好的例子:你要告訴它,你想畫的東西(super.paint(G))母公司

import java.awt.*; 
import javax.swing.*; 

// draw in a JPanel, not in a JFrame 
public class JavaGame2 extends JPanel { 
    private static final int PREF_W = 500; 
    private static final int PREF_H = PREF_W; 

    public JavaGame2() { 

    } 

    // draw within the JPanel's paintComponent method 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); // be sure to first call the super's method 
     g.drawString("Hello world !!!!", 30, 30); 
    }; 

    // better to set size this way 
    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private static void createAndShowGui() { 
     JavaGame2 mainPanel = new JavaGame2(); 

     // no need to extend JFrame. Instead just use one when needed 
     JFrame frame = new JFrame("sadid java game"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     // be sure to start your Swing GUI in a thread-safe way 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
0

首先,我認爲這將工作:

import java.awt.Graphics; 

import javax.swing.JFrame; 

public class JavaGame extends JFrame{ 

    public JavaGame(){ 

     super("sadid java game"); 
     setSize(500, 500); 
     setResizable(true); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 

    public void paint(Graphics g){ 
     super.paint(g); 
     g.drawString("Hello world !!!!",200,300); 


    } 

    public static void main(String[] args) { 
     new JavaGame(); 

    } 

}