Problemas ao desenhar uma imagem numa JFrame

5 respostas
silas_j_ior

To tentando desenvolver uma aplicação que desenhe numa JFrame uma imagem pixel a pixel. A imagem é desenhada na tela, mas um problema apareceu de última hora:

A imagem só vai sendo desenhada quando ou eu maximizo o JFrame ou ainda quando manipulo a barra de rolagem do JFrame. Coloquei um Thread.sleep só para o usuário ir acompanhando o desenho na JFrame pixel a pixel.

Um colega meu disse que esse problema pode ter alguma relação com o refresh do JFrame…Aí quando a gente clica pra maximizar ou mesmo na barra de rolagem ele é atualizado. Eu queria atualizar automaticamente. To aprendendo agora interface gráfica em JAVA…Quem puder ajudar, agradeço.

Segue o código:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;

public class SegundoExemplo {

	public static void main(String[] args) throws IOException, InterruptedException {

		BufferedImage image = ImageIO.read(new File("Imagens/image1.jpg"));
		BufferedImage image2 = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_RGB);;
		WritableRaster raster = image2.getRaster();
	    int width = image.getWidth(),height = image.getHeight(),rgb;
	    int[] imageData = new int[3];
		ImageIcon icon = new ImageIcon(image2);
		JLabel imageLabel = new JLabel(icon);
		JFrame frame = new JFrame();
		
		frame.setTitle("Display");
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(new JScrollPane(imageLabel),BorderLayout.CENTER);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(400,400);
		frame.setVisible(true);

		for(int h=0;h<height;h++)

			for(int w=0;w<width;w++) {

				rgb = image.getRGB(w,h);
				imageData[0] = (int)((rgb&0x00FF0000)>>>16); // R
				imageData[1] = (int)((rgb&0x0000FF00)>>>8); // G
				imageData[2] = (int) (rgb&0x000000FF); // B
				raster.setPixel(w,h,imageData);
				Thread.sleep(0);

			}

	}

}

Vlw =D

5 Respostas

D

Hail

Javadoc do add classe container wrote:

Note: If a component has been added to a container that has been displayed, validate must be called on that container to display the new component. If multiple components are being added, you can improve efficiency by calling validate only once, after all the components have been added.


Ou seja use o método validade() ou até mesmo um repaint().

Abraço

silas_j_ior

Vlw aew =D

Com o repaint() o código ficou funcionando blz! Agora que ele tá funcionando na massa vou trabalhar para que os pixels sejam criados aleatoriamente na tela. Assim que eu fizer posto o código aqui.

Segue o código modificado p/ quem tiver interesse:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;

public class SegundoExemplo {

	public static void main(String[] args) throws IOException, InterruptedException {

		BufferedImage image = ImageIO.read(new File("Imagens/foto0.bmp"));
		BufferedImage image2 = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_RGB);;
		WritableRaster raster = image2.getRaster();
	    int width = image.getWidth(),height = image.getHeight(),rgb;
	    int[] imageData = new int[3];
		ImageIcon icon = new ImageIcon(image2);
		JLabel imageLabel = new JLabel(icon);
		JFrame frame = new JFrame();
		
		frame.setTitle("Display");
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(new JScrollPane(imageLabel),BorderLayout.CENTER);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(400,400);
		frame.setVisible(true);

		for(int h=0;h<height;h++)

			for(int w=0;w<width;w++) {

				rgb = image.getRGB(w,h);
				imageData[0] = (int)((rgb&0x00FF0000)>>>16); // R
				imageData[1] = (int)((rgb&0x0000FF00)>>>8); // G
				imageData[2] = (int) (rgb&0x000000FF); // B
				raster.setPixel(w,h,imageData);
				frame.repaint();
				Thread.sleep(5);

			}

	}

}

Vlws

silas_j_ior

aew galera, fiz agora a modificação do programa para que fosse criada uma imagem, onde os pixels serão desenhados de forma aleatória na JFrame. Sei que o programa num tem utilidade alguma, mas quem quiser ver como funciona tá ai o código:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;

public class SegundoExemplo {

	public static void main(String[] args) throws IOException, InterruptedException {

		BufferedImage image = ImageIO.read(new File("Imagens/foto0.bmp"));
		BufferedImage image2 = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_RGB);;
		WritableRaster raster = image2.getRaster();
	    int width = image.getWidth(),height = image.getHeight(),rgb, alt, larg;
	    int[] imageData = new int[3];
	    boolean[][] positions = new boolean[width][height];
		ImageIcon icon = new ImageIcon(image2);
		JLabel imageLabel = new JLabel(icon);
		JFrame frame = new JFrame();
		
		frame.setTitle("Display");
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(new JScrollPane(imageLabel),BorderLayout.CENTER);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(400,400);
		frame.setVisible(true);
		
		for (int i=0; i<height; i++)
			
			for (int j=0;j<width;j++)
				
				positions[j][i] = false;

		for(int i=0;i<width*height;i++) {
			
			while(true) {
				
				larg = (int)(Math.random()*(width-1));
				alt = (int)(Math.random()*(height-1));
				
				if (positions[larg][alt])
					
					break;
				
				else {
					
					rgb = image.getRGB(larg,alt);
					imageData[0] = (int)((rgb&0x00FF0000)>>>16); // R
					imageData[1] = (int)((rgb&0x0000FF00)>>>8); // G
					imageData[2] = (int) (rgb&0x000000FF); // B
					raster.setPixel(larg,alt,imageData);
					frame.repaint();
					Thread.sleep(0);
					
				}
					
					
			}
			

		}

	}

}

Vlw aew...

Qualquer dúvida tamos aew.

D

Cara se der pra aprender algo já tem utilidade. Salvei teu código aqui, nunca se sabe :wink:

silas_j_ior

Só pra constar: o último código que postei tava entrando num loop infinito e eu num percebi. Vi só hj o problema. To postando o código funcionando blz agora e com algumas modificações.

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;

public class SegundoExemplo {

	public static void main(String[] args) throws IOException, InterruptedException {

		BufferedImage image = ImageIO.read(new File("Imagens/foto63.bmp"));
		BufferedImage image2 = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_RGB);;
		WritableRaster raster = image2.getRaster();
		int width = image.getWidth(),height = image.getHeight(),rgb, alt, larg, contPixels = 0;
		int[] imageData = new int[3];
		boolean[][] positions = new boolean[width][height];
		ImageIcon icon = new ImageIcon(image2);
		JLabel imageLabel = new JLabel(icon);
		JFrame frame = new JFrame();

		frame.setTitle("Display");
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(new JScrollPane(imageLabel),BorderLayout.CENTER);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(400,400);
		frame.setVisible(true);

		for (int i=0; i<height; i++) 

			for (int j=0;j<width;j++) 

				positions[j][i] = false;

		while(true) {

			larg = (int)(Math.random()*(width-1));
			alt = (int)(Math.random()*(height-1));

			if (positions[larg][alt]) {

				if (contPixels == width*height)

					break;

			}

			else {

				rgb = image.getRGB(larg,alt);
				imageData[0] = (int)((rgb&0x00FF0000)>>>16); // R
				imageData[1] = (int)((rgb&0x0000FF00)>>>8); // G
				imageData[2] = (int) (rgb&0x000000FF); // B
				raster.setPixel(larg,alt,imageData);
				frame.repaint();
				positions[larg][alt] = true;
				contPixels++;
				Thread.sleep(0);

			}

		}

	}

}

Realmente…Esse código pode não fazer muita coisa a não ser desenhar a imagem numa JFrame de forma aleatória, mas vai que futuramente sirva pra algo na prática né? :lol:

Vlw aew

Criado 21 de julho de 2009
Ultima resposta 23 de jul. de 2009
Respostas 5
Participantes 2