调整 JPanel 的大小以准备打印,而无需将其从原始位置移开
在我的程序中,我经常需要打印各种 JComponent(通常是 JPanel),并且我喜欢它们是整页的。 我现在这样做的方法是使用以下代码:
g2d.scale(pf.getImageableWidth()/componentToPrint.getWidth(), pf.getImageableHeight()/componentToPrint.getHeight());
但这通常会拉伸或以其他方式使我尝试打印的内容变形,而且我更愿意做一些智能调整大小的事情,也许是以下功能版本:
componentToPrint.setSize(pf.ImageableWidth(), pf.ImageableHeight);
或者说添加将组件放入新的 JFrame 中,然后设置框架大小(问题是组件不能同时存在于两个位置)。 我不在乎调整大小是否会使 GUI 的其余部分看起来很糟糕,只要它可以轻松重置即可。
有什么办法可以做到这一点吗?
In my program I frequently need to print various JComponents (generally JPanels) and I like them to be full-page. The way I do it now is by using the following code:
g2d.scale(pf.getImageableWidth()/componentToPrint.getWidth(), pf.getImageableHeight()/componentToPrint.getHeight());
but this often stretches or otherwise deforms whatever I am trying to print, and I would much prefer to do something that re-sized intelligently, perhaps a functional version of:
componentToPrint.setSize(pf.ImageableWidth(), pf.ImageableHeight);
or say adding the component into a new JFrame and then setting the frame size (problem is components can't exist in two place at once). I wouldn't care if the resizing would make the rest of the GUI look terrible, as long as it is something that can easily be reset.
Is there any way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为您正在寻找的解决方案是构建一个包含所需内容的新 JPanel 并打印副本。 如果您使用 CellRendererPane 执行此操作,您可以获得听起来像您正在寻找的精确大小调整行为。
如果您的 JComponent 编写得相当好,那么新建一个新的 JComponent 并将其模型设置为与原始模型相同应该不是问题。
这是一个完整的工作示例。 createPanel() 方法应该创建您想要呈现的任何组件。 真实的示例应该确保使用相同的模型,而不是为一次性组件重新创建新模型。
I think the solution you're looking for would be to construct a new JPanel that contains the desired contents and to print the copy instead. If you do so using the CellRendererPane you can get the exact resizing behaviour it sounds like you're looking for.
If your JComponents are reasonably well written then it shouldn't be a problem to new up a fresh one and to set its model to be the same as the original's.
Here's a complete working example. The createPanel() method should create whatever component it is that you want rendered. A real example should be sure to use the same model rather than recreating a new model for a throwaway component.
我认为你面临的问题与规模经营无关。 这是你的逻辑不正确。 在大多数情况下,您的 x 和 y 比例会不同,因为 Imageable 的比例和组件的比例不会相同。 这就是缩放操作后组件变形的原因。 您必须执行以下操作:
之后,您可以根据新尺寸将图像转换为适当的坐标。
希望能帮助到你...
I think the problem you're facing has nothing to do with scale operation. It is your logic that is incorrect. In most cases your x and y scales will be different, since the scale of Imageable and and your component's scale will not be the same. This is the reason your component is distorted after the scale operation. You have to do something like:
After that you can translate your image to the appropriate coordinates according to it's new size.
Hope it helps...
我会将
JPanel
实现的paintComponent()
方法中的绘图代码重构为该面板中的公共/包保护方法,该方法可以绘制到任意Graphics
对象,任何宽度/高度(大概绘图代码足够通用)。此示例有一个框架,其中包含一个面板,其中有一些绘图逻辑(一个大 X,面板的大小)。 此示例的主要方法向您展示了一种获取图像并将其写入文件的方法,即使图像大小与面板大小不同也是如此。
这允许 GUI 外部的对象挂接到其绘图算法中。 我发现的一个缺点是,您将在任何想要打印面板的对象与面板的实际实现之间创建依赖关系。 但它仍然比动态调整面板大小要好(我已经尝试过,似乎有一些问题 - 我认为
setSize()
更改需要一些时间才能传播。编辑:
作为对评论的回应,我提供了上面代码片段的修改版本,这可能不是最好的方法,而且不太用户友好(所以我不会 在最终用户应用程序中使用它),但它确实根据布局管理器的规则调整框架中的所有内容的大小。
该代码基本上调整框架的大小,向用户显示确认消息,以便线程可以被阻塞,直到重新绘制。完成(可以通过 Thread.sleep() 完成,但使用消息更透明),然后打印框架并将其大小调整回原始形状。 .
--弗拉维·西普西甘
I would refactor the drawing code out of the
paintComponent()
method of your implementation ofJPanel
to a public/package protected method in that panel which can draw to an arbitraryGraphics
object, of any width/height (presumably that the drawing code is general enough).This example has a frame, containing a panel, which has some drawing logic (a big X, the size of the panel). The main method of this example shows you a way to get an image and write it to a file, even if the image size is different than the panel's size.
This allows objects external to the GUI to hook into its drawing algorithm. One drawback I see is that you will create a dependency between any object wanting to print the panel to the actual implementation of the panel. But it's still better than resizing the panel on the fly (I have tried that and seems to have some issues - I think it takes some time for the
setSize()
change to propagate.EDIT:
In response to the comments, I have provided a modified version of the code snippet above. It is probably not the best way to do it, and not very user friendly (so I wouldn't use it in an end-user application), but it does resize everything in the frame according to the rules of the layout manager.
The code basically resizes the frame, shows the user a confirm message so the thread can be blocked until the repaint is done (could be done by
Thread.sleep()
, but it's more transparent using a message). Then it prints the frame and resizes it back to its original shape. A bit hacky, but it works.-- Flaviu Cipcigan
我想你回答了你自己的问题。 每个组件都有一个方法:
I think you answered your own question. Each Component has a method :