java swing打印文件_java – 打印一个大的Swing组件

我有一个Swing表单,在JScrollPane中有一个自定义表(它只是一个JPanel,而不是JTable子类),我试图让它打印出来.如果我只是将整个框架发送到打印机,滚动窗格会切断,如果我将框架的大小调整为滚动窗格内容的大小,某种内部屏障会阻止JFrame变得超过1100像素高.

另一种方法是创建对话框的内容窗格而不将其附加到根JFrame,因为JPanel的大小在这种情况下不受限制.但是为了让组件自行调整并调整到适当的大小,我似乎需要使面板可显示,这意味着至少将它添加到JFrame并调用JFrame.pack(),但同样,1100像素限制回来了.

这是我打印组件的代码:

public static void print(final Component comp) {

final float SCALE = .5f;

PrinterJob job = PrinterJob.getPrinterJob();

job.setPrintable(new Printable() {

public int print(Graphics g, PageFormat pf, int page)

throws PrinterException

{

if (page * pf.getImageableHeight() >= SCALE * comp.getHeight())

return NO_SUCH_PAGE;

((Graphics2D)g).translate(pf.getImageableX(), pf.getImageableY()

- page * pf.getImageableHeight());

((Graphics2D)g).scale(SCALE, SCALE);

comp.printAll(g);

return PAGE_EXISTS;

}

});

if (job.printDialog())

try { job.print(); }

catch (PrinterException ex) {}

}

如果我这样做,组件的大小为零:

JPanel c = createPanel(); // This JPanel has a JScrollPane in it with its

// preferredSize equal to that of its viewport component

// (which is not what I do to show the dialog normally)

print(c);

如果我这样做,组件具有正确的大小,但打印为纯灰色,因为子组件尚未布局:

JPanel c = createPanel();

c.setSize(c.getPeferredSize());

print(c);

这些似乎没有什么区别:

JPanel c = createPanel();

c.validate();

c.revalidate();

c.repaint();

print(c);

这使面板变大,但它停在大约一页半(1100px):

JPanel c = createPanel();

JFrame f = new JFrame();

f.setContentPane(c);

f.pack();

print(c);

我在这里没有排列.有没有人知道(a)如何更改操作系统最大帧大小,(b)如何布局和绘制离屏组件,或(c)如何直接打印Swing组件,而不必绘制它(?) .感谢帮助.

解决方法:

使用自定义面板的paint()方法,将内容渲染为BufferedImage.

附录:这是一个更完整的方法示例,它只是将组件缩放一半.您需要在实际应用程序中保留纵横比.

import java.awt.Dimension;

import java.awt.EventQueue;

import java.awt.Graphics2D;

import java.awt.GridLayout;

import java.awt.geom.AffineTransform;

import java.awt.image.AffineTransformOp;

import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

/** @see https://stackoverflow.com/questions/7026822 */

public class PanelPaint extends JPanel {

private static final double SCALE = 0.5;

public PanelPaint() {

super(new GridLayout(0, 1));

final MyPanel panel = new MyPanel();

JScrollPane scroll = new JScrollPane(panel);

scroll.getViewport().setPreferredSize(new Dimension(320, 240));

this.add(scroll);

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

add(new JLabel(new ImageIcon(createImage(panel))));

}

});

}

private BufferedImage createImage(MyPanel panel) {

Dimension size = panel.getPreferredSize();

BufferedImage image = new BufferedImage(

size.width, size.height, BufferedImage.TYPE_INT_ARGB);

Graphics2D g2d = image.createGraphics();

panel.paint(g2d);

g2d.dispose();

AffineTransform at = new AffineTransform();

at.scale(SCALE, SCALE);

AffineTransformOp scaleOp =

new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

return scaleOp.filter(image, null);

}

private static class MyPanel extends JPanel {

private static final int N = 16;

public MyPanel() {

super(true);

this.setLayout(new GridLayout(N, N));

for (int i = 0; i < N * N; i++) {

this.add(new JLabel(String.valueOf(i) + " "));

}

}

}

private void display() {

JFrame f = new JFrame("PanelPaint");

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.add(this);

f.pack();

f.setLocationRelativeTo(null);

f.setVisible(true);

}

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

new PanelPaint().display();

}

});

}

}

如图所示,您可以缩放渲染以适合目标的MediaPrintableArea,或使用getSubimage()根据需要将内容划分为页面.

标签:java,printing,swing

来源: https://codeday.me/bug/20190917/1809489.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值