2016-09-21 46 views
1

您好我是新的Java GUI編程。我創建了Jframe(MainFrame)並添加了JPanel(OutPanel),其中有另一個Jpanel(InnerPanel)。我試圖在InnerPanel中實現繪製圖像,而不是繪製OutPanel。我想OutPanel曾經只是Container。正如你看到TestA一樣。我得到GraphicsInnerPanelOutPanelpaintComponent()這是overided方法。使用getGraphics()方法一次無法加載圖像

因此,最後我可以使用InnerPanelGraphicsOutPanelpaintComponent()方法。但它不能很好地工作。程序啓動時無法畫一次Image。當我隱藏窗口並再次顯示時,程序顯示圖像。即使這是圖像的一部分,不是所有的圖像。

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 


public class TestA{ 

    private static Image image = GUI.loadImage("PlayerBoard.jpg"); 


    public static void main(String[] args) { 
     TestA testA = new TestA(); 
    } 


    public TestA() { 

     JFrame mainFrame = new JFrame("Main Frame"); 
     mainFrame.setLayout(null); 
     mainFrame.setSize(500, 500); 
     mainFrame.setVisible(true); 
     mainFrame.setBackground(Color.black); 
     mainFrame.setLocation(800, 400); 

     OutPanel outPanel = new OutPanel(); 

     mainFrame.getContentPane().add(outPanel); 
     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     outPanel.repaint(); 
    } 

    private class OutPanel extends JPanel { 

     JPanel innerPanel; 

     public OutPanel() { 

      this.setLayout(null); 
      this.setLocation(0, 0); 
      this.setSize(500, 50); 
      this.setBackground(Color.red); 

      innerPanel = new JPanel(); 
      this.innerPanel.setSize(400, 50); 
      this.innerPanel.setVisible(true); 
      this.add(innerPanel); 

     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      // TODO Auto-generated method stub 
      super.paintComponent(g); 

      int width = 500; 
      int height = 50; 

      BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE); 
      Graphics gBuffer = resized.createGraphics(); 
      gBuffer.drawImage(TestA.image, 0, 0, width, height, this); 

      Graphics gPanel = innerPanel.getGraphics(); 
      gPanel.drawImage(resized, 0, 0, width, height, this); 
     } 
    } 
} 

所以我嘗試diffrerent方式(TestB)。唯一不同的是我剛剛將drawImage()方法和getGraphics()東西移至InnerPanelpaintComponent()OutPanelpaintComponent()。這是另一個Code TestB。它運作良好。

爲什麼會發生這種情況。它是否與context有關?什麼是Context。並可以畫InnerPanel's Image in OutPanel

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.RenderingHints; 
import java.awt.image.BufferedImage; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class TestB { 

    private static Image image = GUI.loadImage("PlayerBoard.jpg"); 

    public static void main(String[] args) { 
     TestB testB = new TestB(); 
    } 

    public TestB() { 

     JFrame mainFrame = new JFrame("Main Frame"); 
     mainFrame.setLayout(null); 
     mainFrame.setSize(500, 500); 
     mainFrame.setVisible(true); 
     mainFrame.setBackground(Color.black); 
     mainFrame.setLocation(800, 400); 

     OutPanel outPanel = new OutPanel(); 

     mainFrame.add(outPanel); 

     outPanel.repaint(); 

    } 

    private class OutPanel extends JPanel { 

     JPanel innerPanel; 

     public OutPanel() { 

      this.setLayout(null); 
      this.setLocation(0, 0); 
      this.setSize(500, 50); 
      this.setBackground(Color.red); 

      innerPanel = new InnerPanel(this); 
      this.innerPanel.setSize(500, 50); 
      this.innerPanel.setVisible(true); 
      this.add(innerPanel); 

      this.repaint(); 
     } 
    } 

    private class InnerPanel extends JPanel { 

     OutPanel outPanel; 

     public InnerPanel(OutPanel outPanel) { 
      this.outPanel = outPanel; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      // TODO Auto-generated method stub 
      super.paintComponent(g); 

      int width = 500; 
      int height = 50; 

      Graphics2D g2d = (Graphics2D) g; 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      g.drawImage(TestB.image, 0, 0, width, height, this); 
     } 
    } 
} 
+0

'private static Image image = GUI.loadImage(「PlayerBoard.jpg」);''GUI'的代碼在哪裏?在任何情況下,考慮到'static',我只能猜測它試圖通過'File'來加載圖像,並且在那個時候。應用程序資源在部署時將成爲嵌入式資源,所以開始訪問它們是明智的就好像他們現在一樣。 [tag:embedded-resource]必須通過URL而不是文件訪問。請參閱[信息。頁面爲嵌入式資源](http://stackoverflow.com/tags/embedded-resource/info)如何形成的URL。 –

+0

如果幫助解決問題,請[接受答案](http://meta.stackexchange.com/a/5235/155831)。 –

回答

2

組件的paintComponent()方法只負責繪製自己。它不應該知道或關心任何其他組件。

我想OutPanel以前只是容器。

然後就這麼做。創建面板並設置外部面板的佈局管理器,然後將外部面板添加到JFrame。

然後創建您的內部面板並將其添加到外部面板。確保您覆蓋內部面板的getPreferredSize()方法,以便外部面板的佈局管理器可以完成其工作。

閱讀Swing教程Custom Painting中的部分以獲取更多信息和工作示例。

+0

感謝您的回答。那麼,你的意思是外部組件不知道它是否是附加組件之一? –

+0

@DoyoonKim,外部組件不在意。 Swing將自動繪製組件及其所有子組件。繪畫代碼只應該擔心繪畫本身,​​而不是任何兒童(或父母)組件。 – camickr