First, model some classes that describe what you will print and put in them a method responsible for printing them. Let’s see, a reporting of printed products 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 probably want to extend that to other things that you might want to print:
public interface Drawable {
public void draw(int x, int y, Graphics g);
}
Having done so, their 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 block finally
serves in case it finishes the objects even if you pass some Drawable
misbehaved who throw an exception in the method draw
.
The advantage of doing it this way 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 interface Drawable
and that’s it. Also, 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 design, making a Drawable
be composed of other Drawable
s.
Finally, to print any Drawable
, all you will need to do is (after you have created the Drawable
):
imp.imprimir(titulo, x, y, drawable);
If you are with Java 8, you can try a bolder step and make your Drawable
thus:
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 that your method capturaProduto()
gets 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
class Impresso
.
What are the types of
TbProdutosVenda.getValueAt(i, 1)
, ofTbProdutosVenda.getValueAt(i, 2)
, ofTbProdutosVenda.getValueAt(i, 3)
and ofTbProdutosVenda.getValueAt(i, 6)
? I need that information to prepare my answer.– Victor Stafusa
@VictorStafusa, TbProdutosVenda.getValueAt(i, 1) tipo int, TbProdutosVenda.getValueAt(i, 2) tipo String, TbProdutosVenda.getValueAt(i, 3) tipo Double, TbProdutosVenda.getValueAt(i, 6) tipo Double.
– DevAgil
It is Double with upper case or double case?
– Victor Stafusa
By the way, the first is Integer instead of int. Correct?
– Victor Stafusa
this the way I passed it to you above. int and Double.
– DevAgil
Wouldn’t be returning one
List<List<?>>
? OneJTable
can be imagined as an array, returning a single list seems a bit messy. It’s a list even if it needs to return?– Renan Gomes