Problemas com impressão

Pessoal, estou tendo 3 problemas com relatório:

Fiz minha tela de relatório em um painel e usei o método print pra escrever as coisas nele.Mas estou tendo alguns problemas:

Quando coloco pra imprimor não está imprimindo o que deveria, imprime uma folha quase que vazia, sendo que o relatório está cheio.Gostaria de saber tb se dá pra montar todas as páginas de uma vez e ir variando pelos botões avança e recua, porque só quando eu aperto o botão avança ou recua que é montada a próxima página, então demora. Gostaria de saber tb, se tem como deixar o usuário selecionar algo do relatório, que nem acontece com um texto no Word, que dá pra eu selecionar e copiar.

O código fonte é esse:(ele envolve outros arquivos , mas esses problemas que citei acontecem com ele)

import java.awt.;
import java.awt.event.
;
import java.awt.image.;
import java.awt.print.
;
import java.util.;
import javax.swing.
;
import javax.swing.event.*;

public class FormulariodeImpressao extends JDialog{
private int larguraPg,imprimePosicao=40;
private int alturaPg;
private Printable m_target;
private BufferedImage img;
private Graphics g;
private PrinterJob prnJob;
private PageFormat FormatoPagina;

public int indPagina;
public Printable ObjetoaImprimir;

private int pagCorr = 1;
private JScrollPane jScrollPane1 = new JScrollPane();
private JPanel baupg = new JPanel();
private JPanel buttons = new JPanel();
private JPanel left = new JPanel();
private JButton btAvancar = new JButton("Avancar");
private JButton btRecuar = new JButton("Recuar");
private JButton btImprimir = new JButton("Imprimir");
private JLabel lbPagina = new JLabel("Página xxx/xxx");

public FormulariodeImpressao(){
	this.getContentPane().setLayout(new BorderLayout());
	this.setSize(637, 575);
	this.setTitle("Preview de Impressão");
	this.setResizable(false);
	jScrollPane1.getViewport().add(baupg,null);
	this.getContentPane().add(jScrollPane1, BorderLayout.CENTER);
	//Cria os outros objetos
	left.setLayout(new BorderLayout());
	buttons.setLayout(new GridLayout(0,1));
	left.add(buttons, BorderLayout.NORTH);
	this.getContentPane().add(left, BorderLayout.WEST);
	buttons.add(btAvancar);
	btAvancar.addActionListener (new ActionListener(){
		public void actionPerformed(ActionEvent e){
			avanca();
		}
	});
	buttons.add(btRecuar);
	btRecuar.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e){
			recua();
		}
	});
	buttons.add(new JPanel());
	buttons.add(btImprimir);
	btImprimir.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e){
			imprime();
		}
	});

           this.addWindowListener(new WindowAdapter() //Adicionando ouvidor de janela. new WindowAdapter é o gerenciador de eventos.
       { public void windowClosing(WindowEvent e) //WindowAdapter fica gerenciando a janela, se acontecer alguma coisa o gerenciador avisa pro método windowClosing que aconteceu algo, mostrando o parametro, que é o objeto "e", se "e" tiver o evento do "x" de saída vai ser executado o método windowClosing. 
             {
              dispose();   //É obrigado a passar o objeto.
             }
           });

	this.getContentPane().add(lbPagina, BorderLayout.SOUTH);
	//***
            System.out.println("Formulário de Impressão"); 
	show(); 
            setVisible(true);

}

public void montaPag(int num){
	baupg.removeAll();
	try{
		prnJob = PrinterJob.getPrinterJob();
		FormatoPagina = prnJob.defaultPage();
		larguraPg = (int)FormatoPagina.getWidth();
		alturaPg = (int)FormatoPagina.getHeight();
		img = new BufferedImage(larguraPg, alturaPg, BufferedImage.TYPE_INT_RGB);
		g = img.getGraphics();
		g.fillRect(0,0,larguraPg, alturaPg);
		ObjetoaImprimir.print(g, FormatoPagina, num);
		PaginaImpressao pp = new PaginaImpressao(alturaPg, larguraPg,img);
		baupg.add(pp);
	}catch(PrinterException e){
		JOptionPane.showMessageDialog(null, e, "Erro", JOptionPane.ERROR_MESSAGE);
	}
          lbPagina.setText("Página "+num+"/"+indPagina);
}

private Book constroiBook(){
	Book book = new Book();
	book.append(ObjetoaImprimir, FormatoPagina/*, pagCorr*/);
	return book;
}

private void avanca(){
	    //if (pagCorr < indPagina){
                    RelatFunc p=new RelatFunc();
		System.out.println("PAGCORRR p.CountPag "+p.CountPag);
                    
		
                    if(pagCorr<p.CountPag)
                    {
                      pagCorr++;
                      System.out.println("PAGCORRR"+pagCorr); 
                      p.imprimePosicao(pagCorr);
                      System.out.println("PAGCORRR   CHEGOU  :imprimePosicao"+imprimePosicao); 
                      ObjetoaImprimir = (Printable)p;
                      montaPag(pagCorr);
                    }
	//}
}

private void recua(){
	RelatFunc p=new RelatFunc();
	System.out.println("PAGCORRR p.CountPag "+p.CountPag);
                    
		
            if(pagCorr>1)
            {
               pagCorr--;
               System.out.println("PAGCORRR"+pagCorr); 
               p.imprimePosicao(pagCorr);
               System.out.println("PAGCORRR   CHEGOU  :imprimePosicao"+imprimePosicao); 
               ObjetoaImprimir = (Printable)p;
               montaPag(pagCorr);
             }
}
private void imprime(){
	PrinterJob prnJob = PrinterJob.getPrinterJob();
	prnJob.setPageable(constroiBook());
	if (prnJob.printDialog()){
		try{
			prnJob.print();
		}catch(Exception PrinterException){
			JOptionPane.showMessageDialog(null,PrinterException, "Erro", JOptionPane.ERROR_MESSAGE);
		}
	}
}

}

Pessoal, essas ajudas serão muito importantes pra mim e se alguém já fez alguma tela de relatório eu peço que me envie o fonte(bigwaves121084@yahoo.com.br),

valeu a atenção,

Raphael C.