java - 如何在 JPanel 上显示不断变化的 BufferedImage

标签 java swing jpanel bufferedimage

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

以下类位于 Eclipse 中的 SSCCE1 项目中

类 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;
    }
}

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 中设置。

如何纠正这个问题?进行这种类型的可视化的最佳方法是什么,请记住,这里介绍的所有三个类的大小都相当巨大,在实际应用程序中包含很多方法。

最佳答案

(您遇到的)主要问题出在您的 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());
    }
}

此后您需要做的唯一一件事是在重新分配图像后在 setImage 方法中添加 repaint

挑剔

  • 不要使用setBounds,使用LayoutManager,说真的,只要付出努力,它就会给你无尽的返回...
  • 不要重写paint,而是使用paintComponent。这是提供定制绘画的推荐方法。另外,除非您绝对有具体的理由不这样做,否则您必须调用 super.paintXxx,如果不这样做,您最好知道会出现什么问题,以便可以修复它。
  • repaint之后无需调用revalidaterevalidate将自行安排repaint
  • 您可能还想看看 Code Conventions for the Java Programming Language

关于java - 如何在 JPanel 上显示不断变化的 BufferedImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16138836/

相关文章:

Java 图形仅在按钮单击时绘制

java - JPanel 占用的空间超出了它的需要。我怎样才能缩小它?

java - JPanel 绘图故障

java - 如何动态配置应用参数

java - 我们如何才能知道与 documentEvent 中的文档关联的 JeditorPane

Java 方法重载 - 两个列表

java - 如何以编程方式更新 jtable 单元格和 TableModel?

java - 如何将图形放在 JPanel 上?

java.util.NoSuchElementException : No line found when line exists in file

java - JPA合并外键丢失