2013-06-19 75 views
1

我试图在JPanel上呈现动态更改的图像。我已经尝试了很多东西,而我根本没有得到如何去做,或者我做错了什么,而我正处于疯狂的阶段。我是新的摇摆人,这是我的程序中的一个小而重要的部分,它使我能够看到我在做什么。动态更新BufferedImage时遇到问题

简单的要求是最初在下面提到的代码中的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(); 
} 

    } 
+0

您正在将'ImageEditor'放入'ImageEditor'中。那就是你想要的? – jag426

+0

您可能想要尝试实际修改图像本身,而不是每次都替换它,例如,使用'BufferedImage.getRaster()。setPixel(x,y,rgbArray)'替换它。 – AJMansfield

+0

@ jag426我其实不明白你指的是什么。但是,如果是关于ImageEditor类型的JPanel和图像本身,我只想将缓冲的图像放入JPanel并更新。 – Synex

回答

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(); 
} 

} 

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

2

从代码:

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

您正在定义img作为ImageEditor,但你可能意味着这是一个BufferedImage。然后,您将其添加到panel,这是另一个ImageEditor - 但是,当您可能打算使用您编写的方法ImageEditor.setImage()时,它将通过超类方法JPanel.add添加。

编辑:总结:

你描述的更新像素的微小块是BufferedImageimg.img),您ImageEditor img,这反过来ImageEditor panel的内部,这本身就是一个小程序的内容窗格内的内。

  • MainTest类取代static ImageEditor imgBufferedImage img

  • '与img = new BufferedImage()

  • MainTest没什么参构造函数替换panel.add(img)的无参数的构造函数panel.setImage(img)

    取代img = new ImageEditorMainTest
  • BufferedImage mock

  • 更换static ImageEditor mockThirdClass类取代ThirdClass的构造函数ImageEditor img参数与BufferedImage img

  • 更换涉及img任何其他的东西,正确处理它作为一个BufferedImage

还有一件事,虽然这个问题本身并不是程序故障的原因,但你应该重命名Train()方法ThirdClass类似于train(),所以它匹配正确的Java风格。

+0

感谢您指出这一点。是!!!我打算它是BufferedImage。自从我刚离职以来,我无法检查。我会明天检查。 – Synex

+0

我做了修改,但现在更新小方块在那里,但它不是所需的结果。修改后的代码如下\t \t img = new ImageEditor(); panel = new JPanel(); – Synex

+0

@Synex我已经编辑了我的回答,以更清楚地知道我提出的修改是什么。 – AJMansfield