ScrollBar com Método Paint

Boa Noite pessoal, estou quebrando a cabeça para tentar resolver o problema a seguir:

Eu tenho um JFrame com uma barra de rolagem, essa barra deve percorrer uma imagem desenhada ao fundo. Utilizando a imagem como Icon funciona sem problemas, segue o código:

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Desenhar1 extends JFrame {

public static void main(String[] args) {
	EventQueue.invokeLater(new Runnable() {
		public void run() {
			try {
				Desenhar1 frame = new Desenhar1();
				frame.setVisible(true);
				frame.setResizable(false);
				frame.setMinimumSize(new Dimension(400, 300));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	});
}

public Desenhar1() {

	// Painel
	JPanel painel = new JPanel();
	painel.setVisible(true);
	painel.setMinimumSize(new Dimension(800, 600));
	
	// Imagem
	Icon img = new ImageIcon(getClass().getResource("/imagens/mapa.png"));
	JLabel labelImg = new JLabel(img);
	
	// Adiciona o JLabel no JPanel
	painel.add(labelImg);		
	
	// Scroll
	JScrollPane scroll = new JScrollPane();
	scroll.setViewportView(painel);
	setContentPane(scroll);
}
}

Entretanto, preciso que essa imagem inserida seja dinâmica, para isto estou usando o método paint, adaptei o código para ser usada com o método paint (implementado como DesenharTeste):

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Desenhar2 extends JFrame {

public static void main(String[] args) {
	EventQueue.invokeLater(new Runnable() {
		public void run() {
			try {
				Desenhar2 frame = new Desenhar2(); 
				frame.setVisible(true);
				frame.setResizable(false);
				frame.setMinimumSize(new Dimension(400, 300));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	});
}

public Desenhar2() {

	// Painel
	JPanel painel = new JPanel();
	painel.setVisible(true);
	painel.setMinimumSize(new Dimension(800, 600));
	
	// Imagem
	DesenharTeste img = new DesenharTeste();// O mètodo Paint Está Implementado nessa classe		
	img.setVisible(true);

	// Adiciona a imagem no JPanel
	painel.add(img);

	// Scroll
	JScrollPane scroll = new JScrollPane();
	scroll.setViewportView(img);
	setContentPane(scroll);
}
}

Abaixo a implementação do método Paint:

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JComponent;

public class DesenharTeste extends JComponent {

private static final long serialVersionUID = 1L;
private BufferedImage imagemTela;

public DesenharTeste() {
	try {
		InputStream arquivo = getClass().getResourceAsStream("");
		arquivo = getClass().getResourceAsStream("/imagens/mapa.png");
		this.imagemTela = ImageIO.read(arquivo);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

@Override
protected void paintComponent(Graphics g) {
	g.drawImage(imagemTela, 0, 0, this);
}
}

O problema é que dessa segunda forma a barra de rolagem não aparece, e só consigo visualizar a parte correspondente ao tamanho do frame!
Alguém tem alguma ideia de como poderia ser resovido?

Tens que fazer o seu objeto do tipo DesenharTeste ter o tamanho da imagem, para o JScrollPane conseguir calcular os tamanhos das barras.

1 curtida

Era isso que estava faltando, funcionou! Muito obrigado novamente @staroski!
Acrescentei o setPreferredSize logo após que a imagem é carregada, veja como ficou o código:

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Desenhar2 extends JFrame {

public static void main(String[] args) {
	EventQueue.invokeLater(new Runnable() {
		public void run() {
			try {
				Desenhar2 frame = new Desenhar2();
				frame.setVisible(true);
				frame.setResizable(false);
				frame.setMinimumSize(new Dimension(400, 300));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	});
}

public Desenhar2() {

	// Painel
	JPanel painel = new JPanel();
	painel.setVisible(true);
	painel.setMinimumSize(new Dimension(800, 600));
	
	// Imagem
	DesenharTeste img = new DesenharTeste();		
	img.setVisible(true);
	img.setPreferredSize(new Dimension(800,600));// Aqui define o tamanho total da imagem
	// Adiciona a imagem no JPanel
	painel.add(img);

	// Scroll
	JScrollPane scroll = new JScrollPane();
	scroll.setViewportView(img);
	setContentPane(scroll);
}
}

Você poderia ter sobrescrito o método getPrefferedSize pra retornar a largura e altura da imagem carregada.
Daí não precisa se lembrar de chamar o método.