无法动态更新BufferedImage

时间:2013-06-19 19:39:04

标签: java swing jpanel bufferedimage

我正在尝试在JPanel上渲染动态变化的图像。我尝试了很多东西,我根本就没有做到这一点,或者我做错了什么,而且我正处于疯狂的状态。我是新手,这是我的计划中一个小但非常重要的部分,这使我能够看到我在做什么。

简单的要求是最初在JPanel中呈现的图片在下面提到的代码中应该在每个刻度上用随机颜色更新。我无法让图像更新。相反,我得到另一个正方形出现在我正在尝试更新的图像中间,并且小方块会动态变化。我不知道我做错了什么。请让我知道如何纠正下面的代码,以便我可以更新整个图像。

谢谢。

代码如下

(MainTest.java)

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;

public class MainTest extends JFrame {
static ImageEditor img ;
JPanel panel;
Timer to;

public MainTest()
{
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(265, 329);
    getContentPane().setLayout(null);
    img =  new ImageEditor();
    panel = new ImageEditor();
    panel.setBounds(10, 11, 152, 151);
    panel.add(img);
    getContentPane().add(panel);

    JButton btnIterate = new JButton("Iterate");
    btnIterate.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {


            ThirdClass t = new ThirdClass(img);
            to = new Timer(10,t);
            to.start();             
        }

    });
    btnIterate.setBounds(10, 230, 89, 23);
    getContentPane().add(btnIterate);

}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            MainTest frame = new MainTest();
            //frame.getContentPane().add(imgx);
            frame.setVisible(true);
        }
    });

}
}

(ImageEditor.java)
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

@SuppressWarnings("serial")
public class ImageEditor extends JPanel {

private static BufferedImage img = new BufferedImage(100, 100, 1);  
public ImageEditor() {
    render();
}

public void paintComponent(Graphics g) {
    if (img == null)
        super.paintComponents(g);
    else
        g.drawImage(img, 0, 0, this);
}


public void render() {

float cellWidth = 10;
float cellHeight = 10;

    int imgW = img.getWidth();
    int imgH = img.getHeight();
    float r, g, b;
    Graphics2D g2 = img.createGraphics();
    g2.setBackground(Color.black);
    g2.clearRect(0,0,imgW,imgH);
    for (int x=0; x<100; x++) {
        for (int y=0; y<100; y++) {
            r = (float)Math.random();
            g = (float)Math.random();
            b = (float)Math.random();
            g2.setColor(new Color(r,g,b));
            g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight),
                        (int)cellWidth+1, (int)cellHeight+1);
        }
    }
    g2.setColor(Color.black);
    g2.dispose();
    repaint();
}

public BufferedImage getImage() {
    if (img == null)
        img = (BufferedImage)createImage(100, 100);

    return img;
}

public void setImage(BufferedImage bimg) {
    img = bimg;
}
}


(ThirdClass.java)
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class ThirdClass implements ActionListener {

static ImageEditor mock;

public ThirdClass(ImageEditor img)
{
    mock = img;
    Train();
}

public void Train()
{
    mock.render();
}

@Override
public void actionPerformed(ActionEvent arg0) {
    Train();
}

    }

2 个答案:

答案 0 :(得分:2)

来自代码:

img =  new ImageEditor();
panel = new ImageEditor();
panel.setBounds(10, 11, 152, 151);
panel.add(img);
getContentPane().add(panel);

您将img定义为ImageEditor,但您可能认为它是BufferedImage。然后,您将其添加到panel,这是另一个ImageEditor - 但是当您可能想要使用您编写的方法时,它将通过超类方法JPanel.add添加,{{1 }}

编辑:总结:

您所描述的更新像素的一小部分是ImageEditor.setImage()BufferedImage),位于img.img内部,ImageEditor img内部,ImageEditor panel本身在applet的内容窗格中。

  • 使用static ImageEditor img

  • 替换MainTest课程中的BufferedImage img
  • 使用img = new ImageEditor替换MainTest的no-args构造函数中的img = new BufferedImage()

  • 使用panel.add(img)替换MainTest的no-args构造函数中的panel.setImage(img)

  • 使用static ImageEditor mock

  • 替换ThirdClass课程中的BufferedImage mock
  • ImageEditor img替换ThirdClass构造函数中的BufferedImage img参数

  • 替换涉及img的任何其他内容以正确处理BufferedImage

另一件事,虽然这个问题本身并不是导致任何程序故障的原因,但您应该将Train()中的ThirdClass方法重命名为train(),以便它与正确的java匹配风格。

答案 1 :(得分:0)

在我上述问题的第一篇文章之后,我回到了基础,并设法回答了我自己的问题。

我在下面插入完整的代码,因此具有相同问题的另一个用户不必再重复相同的过程。

我的错误非常微不足道。然而,对于开始挥杆的人,我认为这可能会有所帮助

(MainTest.java)
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class MainTest extends JFrame { 

ImageEditor img;
JPanel panel;
Timer t;

public MainTest()
{
    setSize(600,600);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    getContentPane().setLayout(null);

    img = new ImageEditor();
    panel = img;
    panel.setBounds(0, 0, 510, 510);
    getContentPane().add(panel);

    JButton btnStart = new JButton("Start");
    btnStart.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            test();
        }
    });
    btnStart.setBounds(0, 528, 89, 23);
    getContentPane().add(btnStart);
}

private void test() {
    Train tx = new Train(img);
    t = new Timer(100, tx);
    t.start();
}

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

  }

}

(ImageEditor.java)
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

@SuppressWarnings("serial")
public class ImageEditor extends JPanel  {

private static BufferedImage img = new BufferedImage(500, 500, 1);  

public ImageEditor() {
    setLayout(null);
}

public void paintComponent(Graphics g) {
    if (img == null)
        super.paintComponents(g);
    else
        g.drawImage(img, 0, 0, this);
}

public void render() {

float cellWidth = 10;
float cellHeight = 10;

    int imgW = img.getWidth();
    int imgH = img.getHeight();
    float r, g, b;
    Graphics2D g2 = img.createGraphics();
    g2.setBackground(Color.black);
    g2.clearRect(0,0,imgW,imgH);
    for (int x=0; x<100; x++) {
        for (int y=0; y<100; y++) {
            r = (float)Math.random();
            g = (float)Math.random();
            b = (float)Math.random();
            g2.setColor(new Color(r,g,b));
            g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight),
                        (int)cellWidth+1, (int)cellHeight+1);
        }
    }
    g2.setColor(Color.black);
    g2.dispose();
    repaint();
}

public BufferedImage getImage() {
    if (img == null)
        img = (BufferedImage)createImage(500, 500);

    return img;
}

public void setImage(BufferedImage bimg) {
    img = bimg;
}

}

(Train.java this class was named ThirdClass.java in my question)
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Train implements ActionListener {

ImageEditor temp;

Train(ImageEditor img)
{
    temp = img;
}

public void train()
{
    temp.render();  
}

@Override
public void actionPerformed(ActionEvent e) {
    train();
}

}

感谢所有评论和回答我问题的人。