如何使用paintComponent在帧上显示图像

时间:2013-08-08 13:40:24

标签: exception graphics jframe jpanel paintcomponent

这是我的代码:

package com.dani.Game;

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.*;
import java.util.*;

public class Game extends JFrame {

BufferedImage normal;

public static void main(String[] args) {
    Game game = new Game();
}

public Game() {

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    try {
    normal = ImageIO.read(new File("C:\\ImageOne.jpg"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    ImagePanel graphics = new ImagePanel();

    this.add(graphics);
    this.setVisible(true);

}

public class ImagePanel extends JPanel {

   public void paintComponent(Graphics g) {

    super.paint(g);
    g.drawImage(normal,normal.getWidth(), normal.getHeight(), this);

  }
}       

已更新:

当我尝试这个时,我得到了这个例外:

Exception in thread 
     "AWT-EventQueue-0" java.lang.StackOverflowError
    at sun.awt.AppContext.get(Unknown Source)
    at javax.swing.RepaintManager.currentManager(Unknown Source)
    at javax.swing.RepaintManager.currentManager(Unknown Source)
    at javax.swing.RepaintManager.currentManager(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at com.course.swing.headPrac$Drawing.paintComponent(headPrac.java:99)
    at javax.swing.JComponent.paint(Unknown Source)

我做错了什么?

2 个答案:

答案 0 :(得分:1)

无论如何,由于paint和paintComponent之间的调用循环,这将导致Stack Overflow。 将super.paint(g)替换为super.paintComponent(g)作为开始。

无论如何,它的工作形式是我

package com.dani.Game;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

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

public class Game extends JFrame {

    BufferedImage normal;

    public static void main(String[] args) {
        Game game = new Game();
    }

    public Game() {
        this.setLayout(new BorderLayout());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        try {
            normal = ImageIO.read(new File("d:\\providers.gif"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        ImagePanel graphics = new ImagePanel();

        this.add(graphics, BorderLayout.CENTER);
        this.setVisible(true);

    }

    public class ImagePanel extends JPanel {

        public void paintComponent(Graphics g) {

            super.paintComponent(g);
            g.drawImage(normal, 0, 0, normal.getWidth(), normal.getHeight(), this);

        }
    }
}

答案 1 :(得分:1)

我对您的代码进行了一些更改,以使其正常工作。

  • 我在main方法中调用了SwingUtilities invokeLater方法,以确保Swing GUI在Event Dispatch线程(EDT)上启动。必须在EDT上定义和使用Swing GUI 的组件

  • 我使用了JFrame而不是扩展JFrame。当您想要修改其中一个方法时,只需扩展Swing组件。否则,您使用Swing组件。

  • 我在图像文件名中使用了正斜杠。 Java会将forssward斜杠转换为Windows的反斜杠。

  • 我添加了对JFrame pack方法的调用,因此JFrame会将自身调整为图像大小。

  • 我在ImagePanel构造函数中添加了对setPreferredSize方法的调用,以便JPanel的大小与图像大小相同。

  • 我将paintComponent方法中的超级调用更正为super.paintComponent(g)。

  • 我更正了你的drawImage方法,以使用图像的原点,而不是尺寸。

这是代码。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

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

public class Game implements Runnable {

    BufferedImage   normal;

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

    @Override
    public void run() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        try {
            normal = ImageIO.read(new File("C:/ImageOne.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        ImagePanel graphics = new ImagePanel();

        frame.add(graphics);
        frame.pack();
        frame.setVisible(true);
    }

    public class ImagePanel extends JPanel {

        public ImagePanel() {
            setPreferredSize(new Dimension(normal.getWidth(),
                    normal.getHeight()));
        }

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

}