如何在JPanel上显示不断发展的BufferedImage

时间:2013-04-22 03:09:46

标签: java swing jpanel bufferedimage

我需要在JPanel上显示不断发展的BufferedImages。代码的结构如下,我编译了一个SSCCE,如下所示。

以下类位于Eclipse的SSCCE1项目中

Class DisplayLattice.Java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;   
import javax.swing.JPanel;

public class DisplayLattice extends JPanel {

    private BufferedImage IMAGE = null;
    private BufferedImage DISPLAY_IMAGE = null;

    public DisplayLattice()
    {
        IMAGE = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
        render();
    }

    public DisplayLattice(BufferedImage map) {
        IMAGE = map;
        render();
    }

    public void paint(Graphics g) {
        if (IMAGE == null)
            super.paint(g);
        else
            g.drawImage(IMAGE, 0, 0, this);
    }

    public void render() {

    int cellWidth = 5;
    int cellHeight = 5;

        int imgW = IMAGE.getWidth();
        int imgH = IMAGE.getHeight();
        DISPLAY_IMAGE = new BufferedImage(imgW*cellWidth, imgH*cellHeight, 1);          
        Graphics2D g2 = IMAGE.createGraphics();
        g2.clearRect(0,0,DISPLAY_IMAGE.getWidth(),DISPLAY_IMAGE.getHeight());

        for (int x=0; x<imgW; x++) {
            for (int y=0; y<imgH; y++) {
                g2.setColor(new Color(IMAGE.getRGB(x, y)));
                g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight),
                            (int)cellWidth, (int)cellHeight);
            }
        }
        g2.setColor(Color.black);
        g2.dispose();
        repaint();
        revalidate();
        System.out.println("XX");
    }   

    public void setImage(BufferedImage image)
    {
        IMAGE = image;
    }
}

Class SelfOrganizingMap.java

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

public class SelfOrganizingMap {

    public void methodTrain()
    {
        for(int i = 0; i < 100; i++)
        {
            new DisplayLattice(exportImageNorm());
        }

    }

    private BufferedImage exportImageNorm()
    {
        BufferedImage colorNodes = new BufferedImage(200, 200, 1);
        double[][] normL2values = new double[200][200];
        float t = 0.0f;
        for(int i = 0; i < normL2values.length ; i++){
            for(int j = 0; j < normL2values[0].length; j++){
                t = (float) Math.random();
                colorNodes.setRGB(i, j, (new Color(t,t,t)).getRGB());
            }
        }
        System.out.println("LL");
        return colorNodes;
    }

}

以下课程在SSCCE2项目中

类MapScreen.Java(主类)

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class MapScreen extends JFrame {
    private int WIDTH = 0;
    private int HEIGHT = 0;
    private DisplayLattice pnlMap;

    public MapScreen(int mapOption) {


        setType(Type.UTILITY);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setTitle("Map");
        setSize(600, 600);
        setLocation(150,150);
        getContentPane().setLayout(null);

        pnlMap = new DisplayLattice();
        pnlMap.setBounds(6, 130, 582, 440);
        getContentPane().add(pnlMap);

        JButton btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                new SelfOrganizingMap().methodTrain();
            }
        });
        btnNewButton.setBounds(10, 81, 89, 23);
        getContentPane().add(btnNewButton);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                MapScreen frame = new MapScreen(5);
                frame.setVisible(true);
            }
        });

    }
}

我想要实现的是当我单击MapScreen类上的JButton时,我需要JPanel,它是SSCCE1项目中DisplayLattice的一个实例,用于动态更改SelfOrganzingMap类中methodTrain()中指定的迭代次数

我当前遇到的问题是我在每次迭代时在SelfOrganizingMap类中设置的bufferedImage没有在显示的JPanel中设置。

如何纠正这个问题?这种类型的可视化的最佳方式是什么,记住这里提供的所有三个类都非常庞大,实际应用中有很多方法。

1 个答案:

答案 0 :(得分:2)

主要问题(您遇到的问题)在methodTrain方法中。

new DisplayLattice(exportImageNorm());

这只是创建DisplayLattice的新实例,它与实际显示在屏幕上的实例无关......

我能想到的最简单的解决方案是简单地将您在MapScreen中创建的引用传递给methodTrain方法......

new SelfOrganizingMap().methodTrain(pnlMap);

这可以让你做类似的事情......

public void methodTrain(DisplayLattice map) {
    for (int i = 0; i < 100; i++) {
        map.setImage(exportImageNorm());
    }
}

在您重新分配图片后,您需要做的唯一事情就是在repaint方法中添加setImage

Nit挑选

  • 请勿使用setBounds,认真使用LayoutManager,只要付出努力,就会无休止地奖励你......
  • 请勿覆盖paint,而是使用paintComponent。这是提供自定义绘画的推荐方法。另外,除非你绝对有一个具体的理由,否则你必须打电话给super.paintXxx,如果你不这样做,你最好知道会出现什么问题,这样你就可以解决它。
  • revalidate之后无需致电repaintrevalidate将自行安排repaint
  • 您还可以查看Code Conventions for the Java Programming Language