2012-10-25 233 views
2

我有以下簡單的代碼在一個JFrame構造的java的JFrame圖形

super(name); 
    setBounds(0,0,1100,750); 
    setLayout(null); 


    setVisible(true); 

    g = this.getGraphics(); 
    int[] x =new int[]{65, 122, 77, 20, }; 
    int[] y =new int[]{226, 258, 341, 310}; 
    g.setColor(Color.RED); 
    g.drawPolygon (x, y, x.length); 
    System.out.println(g); 

我得到控制檯的輸出爲:

sun.java2d.SunGraphics2D [字體= java.awt.Font中[family = Dialog,name = Dialog,style = plain,size = 12],color = java.awt.Color [r = 255,g = 0,b = 0]]

但是沒有繪製紅色的多邊形在JFrame上,但只是空白的JFrame。

爲什麼?

+0

這不是畫在JFrame的正確方法。您應該繼承JPanel並重寫'paintComponent(Graphics)',並在通過那裏的圖形對象上繪畫。 – Vulcan

回答

7
  • 不要覆蓋paint(..)JFrame

  • 而是添加定製JPanel與重寫paintComponent(Graphics g)JFrame

  • 不使用Null/AbsoluteLayoutuse an appropriate LayoutManager

  • JFrame例如
  • 不要調用setBounds(..)(均不表明其不允許的,但不能看到它在這個應用程序是相關的)

  • 不要忘了使用EDT用於創建和修改GUI組件:

    javax.swing.SwingUtilities.invokeLater(new Runnable() { 
          @Override 
          public void run() { 
           Test test = new Test(); 
          } 
    }); 
    

你會那麼做這樣的事情:

public class Test { 

    /** 
    * Default constructor for Test.class 
    */ 
    public Test() { 
     initComponents(); 
    } 

    public static void main(String[] args) { 

     /** 
     * Create GUI and components on Event-Dispatch-Thread 
     */ 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       Test test = new Test(); 
      } 
     }); 
    } 

    /** 
    * Initialize GUI and components (including ActionListeners etc) 
    */ 
    private void initComponents() { 
     JFrame jFrame = new JFrame(); 
     jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     jFrame.add(new MyPanel()); 

     //pack frame (size JFrame to match preferred sizes of added components and set visible 
     jFrame.pack(); 
     jFrame.setVisible(true); 
    } 
} 

class MyPanel extends JPanel { 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     int[] x = new int[]{65, 122, 77, 20}; 
     int[] y = new int[]{226, 258, 341, 310}; 
     g.setColor(Color.RED); 
     g.drawPolygon(x, y, x.length); 
    } 

    //so our panel is the corerct size when pack() is called on Jframe 
    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(400, 400); 
    } 
} 

主要生產:

enter image description here

+1

+1,很好的例子。好奇的一點是關於setBounds的評論?在使用setLocation和setSize時有什麼區別? – MadProgrammer

+0

@MadProgrammer +1謝謝...至於'setBounds(..)'我沒有具體的證據,但我把它看作是'setSize()'和'setLocation()'的合併。我沒有'setLocation()'的問題(除了位置可能在屏幕外的事實),但是'setSize()'有已知的問題,例如由於給出的尺寸不正確等原因被隱藏的組件等等。使用'setBounds(x,y,width,height)'設置高度和寬度。雖然我是批評:) –

+1

個人我沒有特別的問題,pack和setLocationRelativeXxx通常是更有用的一天一天,恕我直言,雖然它有時必要/可取的直接指定的位置大小。如果沒有充分的理由,這樣會「阻止」以這種方式使用絕對定位,但這只是我。只是想得到你的看法;) – MadProgrammer

2

您應該更好地覆蓋paint(Graphics g)paintComponent(Graphics g)比您嘗試的方法。添加下面的行並刪除代碼中的setVisible之後的行。

public void paint(Graphics g) { 
    int[] x =new int[]{65, 122, 77, 20}; 
    int[] y =new int[]{226, 258, 341, 310}; 
    g.setColor(Color.RED); 
    g.drawPolygon (x, y, x.length); 
} 
+1

並且不使用getGraphics(),此方法用於將圖形打印或保存到文件 – mKorbel

+0

但是,paint方法會在開始時自動運行。我想以編程方式決定何時繪製。 –

+1

然後放上一個標誌,並在油漆下繪製的東西,只有當國旗決定。 –