我不太了解paintComponent如何在Java中工作

时间:2015-01-26 18:37:37

标签: java image swing jframe paintcomponent

我是Java的新手,目前我的水平是打印文本。尽管如此,我想从图形内容开始,但遗憾的是我无法做到。

我从JFrame开始,一切顺利,但是当我不得不打印图像时,我遇到了问题。感谢YouTube,我可以复制这段代码,清楚地显示(但对我来说还不够)如何在JFrame中打印图像。

import java.awt.Graphics;
import javax.swing.*;

public class Main extends JPanel{

  public static void main(String[] args){

    JFrame j = new JFrame("Image");

    j.setSize(1080,720);

    j.setVisible(true);

    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    j.add(new Main());

  }

   public void paintComponent(Graphics g){

    super.paintComponent(g);

    ImageIcon i = new ImageIcon("C:\\Users\\Hello\\Pictures\\picture.jpg");

    i.paintIcon(this, g, 0, 0);

   }

}

老实说,我不明白。我在互联网上寻找解释,但没有答案真的帮助了我。我不理解的基本上是j.add(new Main())(我们是否链接同一个班级?)和paintComponent(Graphics g) ......

1 个答案:

答案 0 :(得分:2)

我不认为我在一个假设的教学例子中看到过这么多错误。

这是重写的代码。您必须将图像放在与Java代码相同的目录中才能读取图像。

package com.ggl.testing;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class DrawImage implements Runnable {

    @Override
    public void run() {
        JFrame j = new JFrame("Image");
        j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        j.add(new ImagePanel(getImage()));

        j.pack();
        j.setLocationByPlatform(true);
        j.setVisible(true);
    }

    private Image getImage() {
        try {
            return ImageIO.read(getClass().getResourceAsStream(
                    "StockMarket.png"));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new DrawImage());
    }

    public class ImagePanel extends JPanel {

        private static final long serialVersionUID = -2668799915861031723L;

        private Image image;

        public ImagePanel(Image image) {
            this.image = image;
            this.setPreferredSize(new Dimension(image.getWidth(null), image
                    .getHeight(null)));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, null);
        }

    }

}

以下是从此代码中获取的重要概念。

  1. 始终通过调用SwingUtilities invokeLater方法启动Java Swing应用程序。这将Swing组件的创建和更新放在Event Dispatch thread (EDT)

  2. 正如其他人提到的那样,在尝试显示之前先阅读图像。如果图像丢失,此代码将异常终止。当您将Java类与JAR文件打包在一起时,此代码也将起作用。

  3. 您没有设置任何尺寸。您可以使用Swing layouts让JFrame和JPanels计算自己的大小。在这个特定示例中,JPanel采用您所读取图像的大小,而JFrame的大小足以容纳图像JPanel。

  4. 您使用Swing组件。如果要覆盖类中的方法,则只扩展Swing组件。在此示例中,我们使用了JFrame并扩展了JPanel。