我需要在 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
之后无需调用revalidate
,revalidate
将自行安排repaint
。 - 您可能还想看看 Code Conventions for the Java Programming Language
关于java - 如何在 JPanel 上显示不断变化的 BufferedImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16138836/