调整 JComponent 的大小以进行文件导出
我有一个 JPanel,在上面使用通常的“paintComponent(Graphics g)”方法绘制了许多自定义编写的 JComponent。我使用 JLayeredPane 来控制自定义组件的显示顺序,如下所示:
public Class MyPanel extends JPanel {
private JLayeredPane layeredPane = new JLayeredPane();
private JComponent component1;
private JComponent component2;
public MyPanel() {
super();
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
component1 = new CustomComponent1();
layeredPane.add (component1, new Integer(0));
component2 = new CustomComponent2();
layeredPane.add (component2, new Integer(1));
add (layeredPane);
}
public void resizePanel(Graphics g, int newWidth, int newHeight) {
component1.setBounds (f(x), f(y), f(newWidth), f(newHeight));
component2.setBounds (f(x), f(y), f(newWidth), f(newHeight));
}
public void paintComponent(Graphics g) {
if ((getWidth() != oldWidth) || (getHeight() != oldHeight)) {
oldWidth = getWidth();
oldHeight = getHeight();
resizePanel (g, getWidth(), getHeight());
}
super.paintComponent(g);
}
现在,我想将此面板导出到 JPEG 文件,但具有不同的大小。当我使用以下代码时,它成功创建/导出所需大小的 JPEG 文件,但它还将面板的屏幕图像版本更新为新大小!哎呀!
public void export(File file, int width, int height)
throws IOException
{
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = scaledImage.createGraphics();
resizePanel (g2, width, height);
super.paintComponent (g2);
try {
OutputStream out = new FileOutputStream(file);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(scaledImage);
out.close();
} catch (FileNotFoundException e) {
throw new IOException ("Unable to export chart to ("
+ file.getAbsolutePath() + "): " + e.getLocalizedMessage());
} finally {
g2.dispose();
}
}
如何“绘制”适合导出的图像,但实际上不会显示该新图像?
谢谢!
好吧,我又回到这个问题了......
我正在绘制的场景包含一些文本,现在最终用户希望以“肖像”长宽比导出图形。由于我不是在新的维度中重新绘制场景,而只是缩放图像,这会导致文本在水平方向上被严重挤压。
无论如何?
I have a JPanel upon which I draw a number of custom-written JComponents using the usual 'paintComponent(Graphics g)' method. I use a JLayeredPane to control the display order of the custom components, as follows:
public Class MyPanel extends JPanel {
private JLayeredPane layeredPane = new JLayeredPane();
private JComponent component1;
private JComponent component2;
public MyPanel() {
super();
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
component1 = new CustomComponent1();
layeredPane.add (component1, new Integer(0));
component2 = new CustomComponent2();
layeredPane.add (component2, new Integer(1));
add (layeredPane);
}
public void resizePanel(Graphics g, int newWidth, int newHeight) {
component1.setBounds (f(x), f(y), f(newWidth), f(newHeight));
component2.setBounds (f(x), f(y), f(newWidth), f(newHeight));
}
public void paintComponent(Graphics g) {
if ((getWidth() != oldWidth) || (getHeight() != oldHeight)) {
oldWidth = getWidth();
oldHeight = getHeight();
resizePanel (g, getWidth(), getHeight());
}
super.paintComponent(g);
}
Now, I would like to export this panel to a JPEG file, but with a different size. When I use the following code, it successfully creates/exports a JPEG file of the desired size, but it also updates my screen image version of the panel to the new size! Yikes!
public void export(File file, int width, int height)
throws IOException
{
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = scaledImage.createGraphics();
resizePanel (g2, width, height);
super.paintComponent (g2);
try {
OutputStream out = new FileOutputStream(file);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(scaledImage);
out.close();
} catch (FileNotFoundException e) {
throw new IOException ("Unable to export chart to ("
+ file.getAbsolutePath() + "): " + e.getLocalizedMessage());
} finally {
g2.dispose();
}
}
How can I 'draw' an image suitable for exporting, but not actually cause this new image to be displayed?
Thanks!
Well, I'm back to this problem again.....
The scene I'm painting includes some text and now the end user wants the graph exported in a 'portrait' aspect ratio. Since I'm not repainting the scene in the new dimensions but just scaling the image, this causes the text to be seriously squashed horizontally.
Anyway around that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看起来是第二个优秀的解决方案。我的最终解决方案如下所示:
Looks like a second excellent solution. The final solution I have looks like the following:
根本不要调整面板的大小;只需创建一个
BufferedImage
这是面板的当前大小并绘制它。获得快照后,立即将其缩放到所需的尺寸BufferedImage
使用drawImage ()
或AffineTransformOp
。附录:
AffineTransformOp< 的一个优点/code>
是对旋转、插值、缩放和纵横比的控制:
Don't resize your panel at all; just create a
BufferedImage
that's the panel's current size and paint it. Once you've got the snapshot, scale it to your desired dimensions in a secondBufferedImage
usingdrawImage()
orAffineTransformOp
.Addendum: One advantage of
AffineTransformOp
is control over rotation, interpolation, scale and aspect ratio:好吧,让一切看起来都正常的唯一方法(例如,在光栅化后不缩放文本)是使用新尺寸在新图形上下文上绘制图像。这是我的新“export()”方法。
上面调用的“draw()”方法在我的所有子组件上调用“setbounds()”方法,将它们绘制到新的缓冲图像上。有点工作,但结果正是我需要的。
Well, the only way I could get everything to look OK (e.g., no scaling of text after it's been rasterized) is to draw the image on a new graphics context using the new size. Here's my new 'export()' method.
The 'draw()' method called above calls the 'setbounds()' method on all of my sub-components which draws them onto the new buffered image. A bit of work, but the result is exactly what I need.