Java重绘重复图像

时间:2013-05-14 06:41:33

标签: java image swing jpanel duplicate-removal

所以我最近做了一些java,我遇到了一些问题。我一直在玩2D绘图并在项目中添加了一个图像。

问题是当窗口调整大小时,它会重绘并复制图像。我做了一些解决方法,但它并不理想......那么为什么图像会重复?

在: http://i.imgur.com/PmHRZBQ.png

(窗口调整大小)

在: http://i.imgur.com/bhsvVZz.png

代码

main.java

import javax.swing.JFrame;


public class main
{
    public static void main(String [] args) throws InterruptedException
    {
        JFrame f = new JFrame("Title");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Canvas testing = new Canvas();

        f.add(testing);
        f.setSize(800, 600);
        f.setVisible(true);
    }
}

canvas.java

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

public class Canvas extends JPanel
{
    public void paintComponent (Graphics g)
    {



        super.paintComponent(g);
        this.setBackground(Color.WHITE);

        g.setColor(Color.BLACK);
        g.fillRect(25, 25, 100, 30);

        g.setColor(new Color(190,81,215));
        g.fillRect(25, 68, 10, 10);

        g.setColor(Color.RED);
        g.drawString("Matt is da best", 100, 10);


            try
            {
                BufferedImage image = ImageIO.read(new File("C:/face.png"));
                JLabel picLabel = new JLabel(new ImageIcon(image));
                System.out.println("Added pic");
                add(picLabel);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }       
    }

}

2 个答案:

答案 0 :(得分:1)

  1. 请勿使用paintComponent(Graphics)方法加载图片!它可以声明为类属性并在构造函数中加载。
  2. 不要在paintComponent方法中添加组件!它会触发重画。
  3. 这应该更可靠..

    import java.awt.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    public class main
    {
        public static void main(String [] args) throws InterruptedException
        {
            JFrame f = new JFrame("Title");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Canvas testing = new Canvas();
    
            f.add(testing);
            f.setSize(800, 600);
            f.setVisible(true);
        }
    }
    
    class Canvas extends JPanel
    {
    
        BufferedImage image;
    
        Canvas() {
            image = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
            JLabel picLabel = new JLabel(new ImageIcon(image));
            System.out.println("Added pic");
            add(picLabel);
        }
    
        public void paintComponent (Graphics g)
        {
            super.paintComponent(g);
            this.setBackground(Color.WHITE);
    
            g.setColor(Color.BLACK);
            g.fillRect(25, 25, 100, 30);
    
            g.setColor(new Color(190,81,215));
            g.fillRect(25, 68, 10, 10);
    
            g.setColor(Color.RED);
            g.drawString("Matt is da best", 100, 10);
        }
    }
    

    其他提示

    • Canvas返回首选尺寸和pack()框架,而不是设置尺寸。
    • 在EDT上启动并更新Swing GUI。
    • 不要为自定义类提供与J2SE类相同的名称。这可能会让人感到困惑。也许称之为JCanvas

答案 1 :(得分:1)

查看您的paintComponent方法......

每次调用paintComponent时,您都会创建一个新的JLabel并将其添加回面板...

try
{
    BufferedImage image = ImageIO.read(new File("C:/face.png"));
    JLabel picLabel = new JLabel(new ImageIcon(image));
    System.out.println("Added pic");
    add(picLabel);
}
catch (IOException e)
{
    e.printStackTrace();
}       

这反过来会产生另一个重绘请求,同步将重新开始。

永远不要在任何paint方法中修改任何组件的状态。这很简单......在你的脸上爆炸......

您应该加载图片并在构造函数中添加标签或其他方法(paintXxx不调用)

关于在Swing中绘画的重要事项是,你无法控制它。重新绘制引擎可以根据自己的需要随时更新您的组件,无论您是否进行了交互。您可以通过致电repaint来鼓励油漆,但不保证何时或将要重新粉刷。