使 JComponent 适合/缩放到正在打印的页面

2023-11-21

我正在尝试缩放我的组件,以便它可以适合单个打印页面(纵向或横向)

 gDiagram.getComponent()

是我要打印的组件(JPanel)。

这是我到目前为止所得到的基于如何打印单个 JPanel 的内容?

/**
 * Prints the diagram.
 */
public void printDiagram() {
    PrinterJob pj = PrinterJob.getPrinterJob();
    pj.setJobName(" Print Component ");

    pj.setPrintable(new Printable() {
        @Override
        public int print(Graphics g, PageFormat pf, int pageNumber)
                throws PrinterException {
            // TODO Auto-generated method stub
            if (pageNumber > 0) {
                return Printable.NO_SUCH_PAGE;
            }

            Graphics2D g2 = (Graphics2D) g;
            g2.translate(pf.getImageableX(), pf.getImageableY());

            double sx = pf.getImageableWidth() / gDiagram.getComponent().getWidth();
            double sy = pf.getImageableHeight() / gDiagram.getComponent().getHeight();

            gDiagram.getComponent().paint(g2);
            g2.scale(sx, sy);
            return Printable.PAGE_EXISTS;
        }
    });

    if (!pj.printDialog()) {
        return;
    }
    try {
        pj.print();
    } catch (PrinterException ex) {
        System.out.println(ex);
    }
}

我对图形不太熟悉,所以任何帮助将不胜感激


基本概念是使用AffineTransformation为结果输出提供缩放。

在我的测试中,我能够拍摄 7680x4800 的图像并打印在 595x842 的页面上(缩小了 93% 左右)

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PrintTest {

    public static void main(String[] args) {
        new PrintTest();
    }

    public PrintTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                final TestPane imagePane = new TestPane();
                JButton print = new JButton("Print");
                print.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        printComponent(imagePane);
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(imagePane);
                frame.add(print, BorderLayout.SOUTH);
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage bg;

        public TestPane() {
            try {
                bg = ImageIO.read(new File("path/to/a/image"));
            } catch (IOException ex) {
                Logger.getLogger(PrintTest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (bg != null) {
                int x = (getWidth() - bg.getWidth()) / 2;
                int y = (getHeight() - bg.getHeight()) / 2;
                g2d.drawImage(bg, x, y, this);
            }
            g2d.dispose();
        }
    }

    public void printComponent(Component comp) {
        PrinterJob pj = PrinterJob.getPrinterJob();
        pj.setJobName(" Print Component ");

        pj.setPrintable(new ComponentPrintable(comp));

        if (!pj.printDialog()) {
            return;
        }
        try {
            pj.print();
        } catch (PrinterException ex) {
            System.out.println(ex);
        }
    }

    public class ComponentPrintable implements Printable {

        private Component comp;

        private ComponentPrintable(Component comp) {
            this.comp = comp;
        }

        @Override
        public int print(Graphics g, PageFormat pf, int pageNumber)
                throws PrinterException {
            // TODO Auto-generated method stub
            if (pageNumber > 0) {
                return Printable.NO_SUCH_PAGE;
            }

            // Get the preferred size ofthe component...
            Dimension compSize = comp.getPreferredSize();
            // Make sure we size to the preferred size
            comp.setSize(compSize);
            // Get the the print size
            Dimension printSize = new Dimension();
            printSize.setSize(pf.getImageableWidth(), pf.getImageableHeight());

            // Calculate the scale factor
            double scaleFactor = getScaleFactorToFit(compSize, printSize);
            // Don't want to scale up, only want to scale down
            if (scaleFactor > 1d) {
                scaleFactor = 1d;
            }

            // Calcaulte the scaled size...
            double scaleWidth = compSize.width * scaleFactor;
            double scaleHeight = compSize.height * scaleFactor;

            // Create a clone of the graphics context.  This allows us to manipulate
            // the graphics context without begin worried about what effects
            // it might have once we're finished
            Graphics2D g2 = (Graphics2D) g.create();
            // Calculate the x/y position of the component, this will center
            // the result on the page if it can
            double x = ((pf.getImageableWidth() - scaleWidth) / 2d) + pf.getImageableX();
            double y = ((pf.getImageableHeight() - scaleHeight) / 2d) + pf.getImageableY();
            // Create a new AffineTransformation
            AffineTransform at = new AffineTransform();
            // Translate the offset to out "center" of page
            at.translate(x, y);
            // Set the scaling
            at.scale(scaleFactor, scaleFactor);
            // Apply the transformation
            g2.transform(at);
            // Print the component
            comp.printAll(g2);
            // Dispose of the graphics context, freeing up memory and discarding
            // our changes
            g2.dispose();

            comp.revalidate();
            return Printable.PAGE_EXISTS;
        }
    }

    public static double getScaleFactorToFit(Dimension original, Dimension toFit) {

        double dScale = 1d;

        if (original != null && toFit != null) {

            double dScaleWidth = getScaleFactor(original.width, toFit.width);
            double dScaleHeight = getScaleFactor(original.height, toFit.height);

            dScale = Math.min(dScaleHeight, dScaleWidth);

        }

        return dScale;

    }

    public static double getScaleFactor(int iMasterSize, int iTargetSize) {

        double dScale = 1;
        if (iMasterSize > iTargetSize) {

            dScale = (double) iTargetSize / (double) iMasterSize;

        } else {

            dScale = (double) iTargetSize / (double) iMasterSize;

        }

        return dScale;

    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使 JComponent 适合/缩放到正在打印的页面 的相关文章

  • 在文本文件中写入多行(java)

    下面的代码是运行命令cmd并使用命令行的输出生成一个文本文件 下面的代码在 Eclipse 的输出窗口中显示了正确的信息 但在文本文件中只打印了最后一行 谁能帮我这个 import java io public class TextFile
  • 如何在android上的python kivy中关闭应用程序后使服务继续工作

    我希望我的服务在关闭应用程序后继续工作 但我做不到 我听说我应该使用startForeground 但如何在Python中做到这一点呢 应用程序代码 from kivy app import App from kivy uix floatl
  • 是什么决定了从 lambda 创建哪个函数式接口?

    请考虑这个例子 import java util function Consumer public class Example public static void main String args Example example new
  • 这个函数(for循环)空间复杂度是O(1)还是O(n)?

    public void check 10 for string i list Integer a hashtable get i if a gt 10 hashtable remove i 这是 O 1 还是 O n 我猜测 O n 但不是
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • JAVA - Xuggler - 组合 MP3 音频文件和 MP4 电影时播放视频

    使用 JAVA 和 Xuggler 以下代码组合 MP3 音频文件和 MP4 电影文件并输出组合的 mp4 文件 我希望在合并音频和视频文件时应自动播放输出视频文件 String inputVideoFilePath in mp4 Stri
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • wait() 在游戏中如何工作?

    在 playframework 的文档中here http www playframework org documentation 1 2 1 asynchronous已写 public static void loopWithoutBlo
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • 匿名类上的 NotSerializedException

    我有一个用于过滤项目的界面 public interface KeyValFilter extends Serializable public static final long serialVersionUID 7069537470113
  • Java 8 流 - 合并共享相同 ID 的对象集合

    我有一系列发票 class Invoice int month BigDecimal amount 我想合并这些发票 这样我每个月都会收到一张发票 金额是本月发票金额的总和 例如 invoice 1 month 1 amount 1000
  • 将 SignedHash 插入 PDF 中以进行外部签名过程 -workingSample

    遵循电子书第 4 3 3 节 PDF 文档的数字签名 https jira nuxeo com secure attachment 49931 digitalsignatures20130304 pdf 我正在尝试创建一个工作示例 其中 客
  • Java 中的“Lambdifying”scala 函数

    使用Java和Apache Spark 已用Scala重写 面对旧的API方法 org apache spark rdd JdbcRDD构造函数 其参数为 AbstractFunction1 abstract class AbstractF
  • Java整数双除法混淆[重复]

    这个问题在这里已经有答案了 方案1 int sum 30 double avg sum 4 result is 7 0 not 7 5 VS 方案2 int sum 30 double avg sum 4 0 Prints lns 7 5
  • 我可以创建自定义 java.* 包吗?

    我可以创建一个与预定义包同名的自己的包吗在Java中 比如java lang 如果是这样 结果会怎样 这难道不能让我访问该包的受保护的成员 如果不是 是什么阻止我这样做 No java lang被禁止 安全管理器不允许 自定义 类java
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • 替换后增量

    我自己已经有一个问题了 但我想扩展它后增量示例 https stackoverflow com questions 51308967 post increment with example char a D int b 5 System o
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 在 RESTful Web 服务中实现注销

    我正在开发一个需要注销服务的移动应用程序 登录服务是通过数据库验证来完成的 现在我陷入了注销状态 退一步 您没有提供有关如何在应用程序中执行身份验证的详细信息 并且很难猜测您在做什么 但是 需要注意的是 在 REST 应用程序中 不能有会话
  • 如何在 JFreeChart 中设置多个系列的线条粗细?

    我创建了很多图表 在他们每个人中我都需要打电话 renderer setSeriesStroke i new BasicStroke 2 0f 对于每个系列 renderer is chart getXYPlot getRenderer 我

随机推荐

  • 在特定位置截断 UILabel

    我使用表格视图显示书籍列表 其中每个单元格都有一个UILabel显示书名和另一本书UILabel显示该书的作者 我的问题是关于作者标签的 一本书可以有多个作者 我希望它的行为如下 如果书只有一位作者 约翰 科尔曼 标签应为 约翰 科尔曼 如
  • 需要默认选择 Angular JS 单选按钮

    我是 Angular JS 的新手 我正在尝试创建一组单选按钮 创建按钮是很容易的部分 但我在弄清楚如何默认选择其中一个而不破坏所有内容时遇到问题 我已经在 Angular 文档和多个其他 stackoverflow 问题中阅读了有关使用
  • 临时约束需要需要需要需要吗?

    假设我正在编写一个类模板 其中一些成员的存在受到限制和价值类型模板参数 static constexpr 数据成员的 template
  • 如何在没有连接的情况下同步管理器/工作线程?

    我熟悉多线程 并成功地用 Java 和 Objective C 开发了许多多线程程序 但如果不使用主线程的连接 我无法使用 pthreads 在 C 中实现以下目标 include
  • Angular 5 - 如何在 DatePipe 中使周期字段类型小写

    在 Angular 5 1 中使用 DatePipe 我需要将周期字段类型 AM PM 设置为小写格式 根据文档 Tuesday December 19 7 00 am 应该 date EEEE MMMM d h mm a 但是 句点字段类
  • 更改 Java printf 中的默认填充字符?

    如果我们这样做System out printf 10s 1 默认情况下 会添加空格字符来填充10 对吧 有办法改变这个吗 我知道 你可以添加0 通过指定0之前s 但是确实printf支持其他什么吗 没有 空间是硬编码的 这是 java u
  • PHP 函数参数错误抑制、empty() isset() 模拟

    我很确定这个问题的答案是否定的 但万一有一些 PHP 大师 是否可以以一种可以传入无效参数或不存在的变量的方式编写一个函数 并且在不使用 php 的情况下不会出错 就像empty和isset一样 你可以传入你刚刚编写的变量 不会出错 ex
  • 表单主题日期时间小部件 Symfony 2

    我喜欢在表单中 形成主题 我的日期时间小部件 我创建了一个 fields html twig 文件 其中包含以下内容 block datetime widget spaceless div day month year replace da
  • strptime、as.POSIXct 和 as.Date 返回意外的 NA

    当我尝试解析以下格式的时间戳时 Thu Nov 8 15 41 45 2012 仅NA被返回 我使用的是 Mac OS X R 2 15 2 和 Rstudio 0 97 237 我的操作系统的语言是荷兰语 我认为这与它有关 当我尝试时st
  • 脚本 @php artisan package:discover --ansi 处理返回的 post-autoload-dump 事件,错误代码为 -1073741819

    从我的 github 中拉出一个项目后 我收到了一些奇怪的错误代码 我做的第一件事是composer dumpautoload composer update and php artisan migrate fresh seed每当我到达新
  • Django:内置密码重置视图

    我正在遵循文档 当我单击页面以重新启动密码时 出现 NoReverseMatch 错误 resetpassword 处无反向匹配 与 password reset done 相反 未找到参数 和关键字参数 尝试了 0 个模式 urls py
  • iOS 分发证书过期会怎样?

    我现在正在向 iTunes connect 提交 iPhone 应用程序 我有一个关于分发证书的问题 如果分发证书过期会发生什么 用户购买的应用程序在证书过期后会停止运行或崩溃吗 或者分发证书过期后用户无法安装应用程序或无法从App Sto
  • 是否可以在不使用偏移量的情况下将指针存储在共享内存中?

    当使用共享内存时 每个进程可以将共享区域映射到其各自地址空间的不同区域 这意味着当在共享区域中存储指针时 您需要将它们存储为偏移量共享区域的开始 不幸的是 这使原子指令的使用变得复杂 例如 如果您尝试编写一个无锁算法 例如 假设共享内存中有
  • 如何使用 Bing 地图检索邮政地址的纬度和经度?

    我希望能够检索给定地址的地理坐标 纬度和经度 我希望如果我有完整的地址 街道地址 城市 州 邮政编码 我可以做到这一点 如果重要的话 我正在使用 Bing 地图 我得到的框架代码是这样的 fullAddress AddPushpin 和 g
  • 使用node.js读取Excel文件

    好的 所以我正在使用FileUploader将我的文件从 Angular 上传到我的模块REST API var uploader scope uploader new FileUploader url api getUrl uploadC
  • JavaScript:如何找出浏览器窗口中视口的宽度和高度?

    如何找出浏览器窗口中视口的宽度和高度 如何找出有多少文档向下和向右滚动 尝试这个函数 并在需要时调用它 function getViewPortSize var viewportwidth var viewportheight Standa
  • Emberjs 异步路由

    我的问题与问题相关 1183 and 1268emberjs 的 我在路线上有动态元素 如果我通过应用程序导航 一切都可以 问题是当我重新加载页面或输入网址时 在这种情况下 应用程序进入反序列化函数并通过其 id 加载和对象 但此加载是异步
  • 是什么导致了 java.lang.ArrayIndexOutOfBoundsException 以及如何防止它?

    什么是ArrayIndexOutOfBoundsException意思是我该如何摆脱它 下面是触发异常的代码示例 String names tom bob harry for int i 0 i lt names length i Syst
  • 存储过程返回错误的标量值 -1,而不是返回值

    我正在尝试从存储过程返回标量值 我实际上想返回新创建的记录的 ID 但我已将问题简化为需要一个存储过程int并尝试返回相同的内容int 这始终返回 1 非常感谢您的帮助 Web API 控制器调用 var idtest dbconn my
  • 使 JComponent 适合/缩放到正在打印的页面

    我正在尝试缩放我的组件 以便它可以适合单个打印页面 纵向或横向 gDiagram getComponent 是我要打印的组件 JPanel 这是我到目前为止所得到的基于如何打印单个 JPanel 的内容 Prints the diagram