First, model some classes that describe what you are going to print, and put them into a method responsible for printing them. Let's see, a printed product report has several printed products and each printed product has code, name, quantity and price. Therefore:
public class ProdutoImpresso implements Drawable {
private final String codigo;
private final String nome;
private final String quantidade;
private final String preco;
public ProdutoImpresso(String codigo, String nome, String quantidade, String preco) {
this.codigo = codigo;
this.nome = nome;
this.quantidade = quantidade;
this.preco = preco;
}
@Override
public void draw(int x, int y, Graphics g) {
g.drawString("Código: " + codigo, x, y);
g.drawString("Nome: " + nome, x, y + 25);
g.drawString("Quantidade: " + quantidade, x, y + 50);
g.drawString("Preço: " + preco, x, y + 75);
}
}
public class RelacaoDeProdutos implements Drawable {
private final List<ProdutoImpresso> itens;
public RelacaoDeProdutos(List<ProdutoImpresso> itens) {
this.itens = itens;
}
@Override
public void draw(int x, int y, Graphics g) {
g.drawString("Relação de produtos", x, y);
int y2 = y + 40;
for (ProdutoImpresso i : itens) {
i.draw(x, y2, g);
y2 += 125;
}
}
}
That interface there is because you'll probably want to extend it to other things you might want to print:
public interface Drawable {
public void draw(int x, int y, Graphics g);
}
Having done this, your other classes become simple:
public void capturaProduto() {
List<ProdutoImpresso> lp = new ArrayList<>();
for (int i = 0; i < TbProdutosVenda.getRowCount(); i++) {
ProdutoImpresso item = new ProdutoImpresso(
TbProdutosVenda.getValueAt(i, 1).toString(),
TbProdutosVenda.getValueAt(i, 2).toString(),
TbProdutosVenda.getValueAt(i, 3).toString(),
TbProdutosVenda.getValueAt(i, 6).toString());
lp.add(item);
}
RelacaoDeProdutos r = new RelacaoDeProdutos(lp);
imp.imprimir("MP4200", 50, 30, r);
}
public void imprimir(String titulo, int x, int y, Drawable toDraw) {
Frame f = new Frame("Frame temporário");
f.pack();
Toolkit tk = f.getToolkit();
PrintJob pj = tk.getPrintJob(f, titulo, null);
Graphics g = null;
try {
if (pj != null) {
g = pj.getGraphics();
toDraw.draw(x, y, g);
}
} finally {
if (g != null) g.dispose();
if (pj != null) pj.end();
f.dispose();
}
}
The finally
block is used in case it finalizes the objects even if you pass some misbehaved Drawable
throw an exception in the draw
method.
The advantage of doing this is that whenever you have something that can be drawn on the screen, in the printer or somewhere else, you just have to implement the Drawable
interface and that's it. In addition, whenever you have a complex object to be printed / drawn on the whole, it is worth using the strategy that each part is responsible for its own drawing, making a Drawable
composed of other Drawable
s. >
Finally, to print any Drawable
, all you need to do is (after you have created Drawable
):
imp.imprimir(titulo, x, y, drawable);
If you have Java 8, you can try a bolder step and make your Drawable
like this:
public interface Drawable {
public void draw(int x, int y, Graphics g);
public default void imprimir(String titulo, int x, int y) {
Frame f = new Frame("Frame temporário");
f.pack();
Toolkit tk = f.getToolkit();
PrintJob pj = tk.getPrintJob(f, titulo, null);
Graphics g = null;
try {
if (pj != null) {
g = pj.getGraphics();
draw(x, y, g);
}
} finally {
if (g != null) g.dispose();
if (pj != null) pj.end();
f.dispose();
}
}
}
And with this your capturaProduto()
method looks like this:
public void capturaProduto() {
List<ProdutoImpresso> lp = new ArrayList<>();
for (int i = 0; i < TbProdutosVenda.getRowCount(); i++) {
ProdutoImpresso item = new ProdutoImpresso(
TbProdutosVenda.getValueAt(i, 1).toString(),
TbProdutosVenda.getValueAt(i, 2).toString(),
TbProdutosVenda.getValueAt(i, 3).toString(),
TbProdutosVenda.getValueAt(i, 6).toString());
lp.add(item);
}
RelacaoDeProdutos r = new RelacaoDeProdutos(lp);
r.imprimir("MP4200", 50, 30);
}
And then you no longer need to use the object imp
of class Impresso
.