Java 强制paintAll()绘制不可见的JPanel及其组件?
我正在把一系列的JPanel打印到一个基本的打印界面上,这个界面提供了一个图形对象,你可以画出你想要打印的东西。如果我有一个“实时”JPanel,它在UI的某个地方,一切都很好 但是,如果我创建了一个JPanel,但从未将其添加到UI中,printAll()似乎什么都不做。将代码缩减为SSCCE:Java 强制paintAll()绘制不可见的JPanel及其组件?,java,swing,graphics,printing,bufferedimage,Java,Swing,Graphics,Printing,Bufferedimage,我正在把一系列的JPanel打印到一个基本的打印界面上,这个界面提供了一个图形对象,你可以画出你想要打印的东西。如果我有一个“实时”JPanel,它在UI的某个地方,一切都很好 但是,如果我创建了一个JPanel,但从未将其添加到UI中,printAll()似乎什么都不做。将代码缩减为SSCCE: import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import javax.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SSCCEPaintInvisible
{
public static void main(String[] args)
{
/* Create an JPanel with a JLabel */
JPanel panel = new JPanel();
//panel.setLayout(new FlowLayout());
JLabel label = new JLabel("Hello World");
panel.add(label);
//label.invalidate();
//panel.invalidate();
/* Record a picture of the panel */
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = image.getGraphics();
/* Draw something to ensure we're drawing */
g.setColor(Color.BLACK);
g.drawLine(0, 0, 100, 100);
/* Attempt to draw the panel we created earlier */
panel.paintAll(g); // DOES NOTHING. :(
/* Display a frame to test if the graphics was captured */
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label2 = new JLabel( new ImageIcon(image) );
frame.add(label2);
frame.pack();
frame.setVisible(true);
// shows ONLY the black line we drew in the Graphics
}
}
如果我为面板创建一个JFrame,并将面板添加到JFrame中,并在调用paintAll()之前使JFrame可见,那么代码会按预期将UI捕获到图形中。当然,这会在屏幕上闪烁一个JFrame来打印它
有没有办法将从未添加到UI的JPanel呈现到图形对象中?谢谢 来自@Kleopatra答案的提示
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class SSCCEPaintInvisible
{
public static void main(String[] args)
{
/* Create an JPanel with a JLabel */
JPanel panel = new JPanel();
JLabel label = new JLabel("Hello World");
panel.add(label);
// Next 3 are very important!
panel.setSize(panel.getPreferredSize());
panel.addNotify();
panel.doLayout();
/* Record a picture of the panel */
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = image.getGraphics();
/* Draw something to ensure we're drawing */
g.setColor(Color.BLACK);
g.drawLine(0, 0, 100, 100);
/* Attempt to draw the panel we created earlier */
panel.paintAll(g); // DOES NOTHING. :(
/* Display a frame to test if the graphics was captured */
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label2 = new JLabel( new ImageIcon(image) );
frame.add(label2);
frame.pack();
frame.setVisible(true);
// shows ONLY the black line we drew in the Graphics
}
}
正如@GagandeepBali所指出的,此GUI不是在EDT上创建的。如果没有在EDT上更改GUI,结果将是不可预测的。有关更多详细信息,请参见&特别是 “但是,如果我创建了一个JPanel,但从未将其添加到UI中,printAll()似乎什么都不做”检查有关绘制未实现组件的提示。+1到SSCCE。尽管创建一个SSCCE时,请务必遵循Swing编程的最佳实践,即使用事件调度线程,而不是将所有内容都放在主方法上。顺便问一下,从左上角到100100之间的黑线之外,您到底希望在图像中看到什么?@AndrewThompson,JPanel中JLabel的“Hello World”。哦,对了,请原谅我的愚蠢我希望有一天我能知道这一点,实际上否决你的帖子:-),但我怀疑,这一天很快就会到来。但希望我每天都能学到新的东西:-)@GagandeepBali“实际上否决你的帖子”(咯咯笑),你会惊讶于我发布的一些明显“在你的雷达下”的东西。使用可怕的代码,修复一两行代码,然后按原样将其转储(这有时是我的哲学)。对OP来说,不要感到困惑,你的代码并不“可怕”,但在这里张贴的问题中,大部分代码都是。@GagandeepBali(和乌托邦天堂)见最后一段。:)