0

我需要在 JPanel 上显示不断变化的 BufferedImages。代码的结构如下所示,我编译了一个 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 中设置。

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

4

1 回答 1

2

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

new DisplayLattice(exportImageNorm());

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

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

new SelfOrganizingMap().methodTrain(pnlMap);

这将允许您执行类似...

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

之后您需要做的唯一另一件事是repaintsetImage重新分配图像后添加方法。

挑剔

  • 不使用setBounds,使用a LayoutManager,认真,努力,它会给你无尽的回报......
  • 不要覆盖paintpaintComponent而是使用。这是提供自定义绘画的推荐方法。此外,除非您绝对有具体的理由不这样做,否则您必须打电话super.paintXxx,如果不这样做,您最好知道会出现什么问题,以便您可以修复它。
  • 无需调用revalidateafter repaintrevalidaterepaint自行安排。
  • 您还可能想看看Java 编程语言的代码约定
于 2013-04-22T03:26:23.420 回答