[RESOLVIDO] Como passar JPanel corretamente?

3 respostas
Vingdel

Bom dia, pessoal!

Criei a seguinte classe:
public class CutImage extends JPanel {
	BufferedImage img, imgCutted;
	private Dimension imgSize, cutSize;
	JFileChooser chooser;
	File curDir;
	private String imgPath, imgName;
	boolean cutter = false;

	CutImage() {
		chooser = new JFileChooser();
		// Seta o diretório de abertura
		if (curDir != null)
			chooser.setCurrentDirectory(curDir);
		// Seta filtro de arquivo
		chooser.setFileFilter(new FileFilter() {
			public boolean accept(File f) {
				return (f.getName().endsWith(".bmp")) || f.isDirectory();
			}

			public String getDescription() {
				return "Imagem BMP do Windows (*.bmp)";
			}
		});
		// variável para receber resultado da abertura de arquivo
		int returnValue = chooser.showOpenDialog(this);
		if (returnValue == JFileChooser.APPROVE_OPTION) {
			// Salava último diretório acessado pelo chooser
			curDir = chooser.getCurrentDirectory();
			/*
			 * Retorna o nome do arquivo chooser.getSelectedFile().getName();
			 * Retorna o diretótio chooser.getSelectedFile().getParent();
			 * Retorna o diretório/arquivo
			 * chooser.getSelectedFile().getAbsolutePath();
			 */
			imgName = chooser.getSelectedFile().getName();
			imgPath = chooser.getSelectedFile().getAbsolutePath();
			try {
				img = ImageIO.read(new File(imgPath));
			} catch (IOException e) {
				e.printStackTrace();
			}
			// Armazena dimesão da imagem
			imgSize = new Dimension(img.getWidth(), img.getHeight());
		}
	}

	// Getters e Setters

	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		// Alinha o centro da imagem ao centro do Conteiner
		int x = (getWidth() - imgSize.width) / 2;
		int y = (getHeight() - imgSize.height) / 2;
		if (cutter)
			g2.drawImage(imgCutted, x, y, this);
		else
			g2.drawImage(img, x, y, this);
	}

	public JPanel printImg() {
		this.setPreferredSize(imgSize);
		JPanel p = this;
		return p;
	}

	public JPanel printCutted(int width, int height) {
		cutSize = new Dimension(width, height);
		imgCutted = img.getSubimage(0, 0, cutSize.width, cutSize.height);
		cutter = true;
		this.setPreferredSize(cutSize);
		JPanel p = this;
		return p;
	}
}

Na minha classe principal, na ação de um JButton, instancio a classe acima, que basicamente abre um BMP, e passo para um JScrollPane com setViewportView() usando o método printImg(), tudo funciona perfeito, a imagem que escolho aparece o JScrollPane. Em outro JButton eu passou a mesma instância para outro JScrollPane, porém agora usando o método printCutted(int, int), a imagem cortada aparece no segundo JScrollPane perfeitamente, porém a imagem do primeiro JScrollPane some.

Entendo que isso acontece pois é a mesma instância, porém dentro de cada método (printImg e printCutted) crio uma nova instância de um JPanel e com uma cópia da classe e ao meu ver cada método passaria um JPanel independente do outro, mas isso não está acontecendo. Como resolvo essa situação?

Desde já agradeço pela ajuda.

Abraço!

3 Respostas

ViniGodoy

Essa linha:

JPanel p = this;

Não está nem criando uma nova instância, nem fazendo uma cópia.
Está apenas criando uma referência para o próprio painel.

Se você quiser fazer cópias, precisa implementar a interface Cloneable e o método clone. E então chamar:

JPanel p = this.clone();
Vingdel

Boa tarde, ViniGodoy!

Eu imaginei que você seria uma das pessoas que viria com a solução, ficou assim:
public CutImage printImg() {
		this.setPreferredSize(imgSize);
		CutImage p = null;
		try {
			p = (CutImage) this.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return p;
	}

	public CutImage printCutted(int width, int height) {
		cutSize = new Dimension(width, height);
		imgCutted = img.getSubimage(0, 0, cutSize.width, cutSize.height);
		cutter = true;
		this.setPreferredSize(cutSize);
		CutImage p = null;
		try {
			p = (CutImage) this.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return p;
	}
Agora está tudo correndo perfeitamente, mas essas seria a forma mais indicada de fazer isso? Você indicaria fazer de outra forma?

Muito obrigado pela atenção e um abraço!

Vingdel

Alguém tem uma avaliação ou uma sugestão de como poderia ser feito melhor?

Abraço!

Criado 10 de maio de 2012
Ultima resposta 16 de mai. de 2012
Respostas 3
Participantes 2