2013-07-29 137 views
0

我試圖繪製簡單的圖形與畫布,在這個類我已經設置了繪畫繪圖畫布上的JFrame

public class Game extends Canvas{ 
    //FIELDS 
    public int WIDTH = 1024; 
    public int HEIGHT = WIDTH/16 * 9; 

    //METHODS 
    public void start(){ 
     Dimension size = new Dimension (WIDTH, HEIGHT); 
     setPreferredSize(size); 
     paint(null); 
    } 

    public void paint(Graphics g){ 
     g.setColor(Color.GREEN); 
     g.fillRect(0, 0, WIDTH, HEIGHT); 
     g.setColor(Color.BLACK); 
     g.fillOval(100, 100, 30, 30); 
    } 
} 

而在這個窗口

public class MainW { 


    public static void main(String[] args) { 
     Game ga = new Game(); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.add(ga); 
     frame.setVisible(true); 
     ga.start(); 

    } 

} 

它的工作原理,但JFrame不適應Canvas。我必須手動調整窗口大小才能看到對象。我如何打包它以便JFrame自動包含Canvas?

編輯: 這真是不可思議。雖然frame.pack()確實很重要,但這還不夠。 我所做的更改啓動方式,把它變成一個構造函數,這樣的:

public class Game extends Canvas{ 
     //FIELDS 
     public int WIDTH = 1024; 
     public int HEIGHT = WIDTH/16 * 9; 

     //METHODS 
     public void Game(){ 
     Dimension size = new Dimension (WIDTH, HEIGHT); 
     setPreferredSize(size); 
    } 

屆時,來自其他類,Eclipse的抱怨直接調用構造函數(EG ga.Game),所以我也跟着它的尖端和更改爲:

public static void main(String[] args) { 
     Game ga = new Game(); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.add(ga); 
     frame.setVisible(true); 
     ga.getName(); 

    } 

這樣,我實現我的想法,但我真的不知道爲什麼我不能調用構造函數是什麼。

+1

讀添加'frame.pack();''之間添加(GA)'和'調用setVisible(真)'。 – johnchen902

+2

不要將AWT和Swing組件不必要地混合在一起。 YOu應該在JPanel和其'paintCompoment(...)'覆蓋方法上繪圖。 –

回答

5

我不知道它是什麼,你現在要做的,但你千萬不要被調用paint,特別是通不過null

首先看看Performing Custom PaintingPainting in AWT and Swing以瞭解有關繪畫如何工作的詳細信息。

爲了得到窗口大小給你的組件,你需要爲它提供了一些重要的信息。

雖然Window#pack是您正在尋找的方法,但它不會幫助您,除非您提供適當的尺寸提示。

在這種情況下,你需要重寫的你的getPreferredSize方法組件,並提供適當的大小的值。 Window#pack將使用此值來確定它需要的尺寸以適應它。

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestPaint { 

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

    public TestPaint() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

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

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.GREEN); 
      g.fillRect(0, 0, WIDTH, HEIGHT); 
      g.setColor(Color.BLACK); 
      g.fillOval(100, 100, 30, 30); 
     } 
    } 
} 

油漆鏈是非常重要的,你應該避免不惜一切海岸打破它。確保您隨時來電super.paintXxx或一些嚴重的古怪準備

可能還需要有Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

0

在畫布上畫後試圖重新繪製JFrame

public static void main(String[] args) { 
    Game ga = new Game(); 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setLocationRelativeTo(null); 
    frame.add(ga); 
    frame.setVisible(true); 
    ga.start(); 

    //repaint here 
    frame.repaint(); 
} 

還要注意的是:

frame.pack固定大小的問題。

frame.revalidate添加或刪除運行時組件時,有時幫助。

2

java.awt.Window.pack使用(JFrame間接延伸Window):

此窗口的大小,以適合其子組件的優選尺寸和佈局。

// ... 
    frame.add(ga); 
    frame.pack(); 
    frame.setVisible(true); 
    // ...