2016-09-21 23 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