2013-07-29 121 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); 
    // ...