所以这个问题有两个部分,我认为可能是相关的,而且大多是抽象的。简而言之,这就是我正在做的事情:
我有一个JFrame
with a JPanel
还有一些child
JPanels
每个有 3 个JButtons
在上面。我还创建了一个JComponent
called glassPanel
为了JFrame
(i.e. myJFrame.setGlassPane(glassPanel)
),这使我能够在 JPanel 和按钮上进行绘制。
(1) 本质上是通过单击 a 上的所有 3 个按钮来触发JPanel
, glassPanel
被设定为Visible
(这似乎然后调用paintComponent()
)。这与第一个问题有关。
(2) In paintComponent()
我使用双缓冲 http://www.cs.tut.fi/lintula/manual/java/tutorial/uiswing/painting/overview.html, onto glassPanel
。这涉及到第二个问题。
这是我的相关 GlassPanel 类代码(这不是 SSCCE,因为它现在是一个抽象问题):
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
public class GlassPanel extends JComponent {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
setDoubleBuffered(true);
Graphics2D g2 = (Graphics2D) g;
g2.drawRect(x,y,width,height);
g2.fillRect(x,y,width,height);
g2.drawImage(img, x, y, this);
}
}
通过放置一个System.out.print
在 PaintComponent() 方法中的声明,我可以告诉它被连续地和异步地调用。有关我认为如何进行调用的信息,请参阅 (1)。另外,假设我绝对确定没有人打电话给repaint()
代码中的任何位置(我已经检查了很多很多次)。这是第一个问题的基础。
我第一次点击 3 个按钮时,一切都很顺利。矩形和图像都会立即绘制。但是,当我单击接下来的 3 个按钮时(此时,glassPanel
已经是setVisible(true)
第一个矩形和图像仍在屏幕上,绘制在前 3 个按钮上),第二个矩形和图像仅部分加载。当我点击远离JFrame
并进入我运行程序的 Eclipse 窗口,调用次数paintComponent()
每次快速增加相同的量并且部分加载的图像和矩形立即完全显示在背景中JFrame
。当我单击返回 JFrame 时,调用数量再次增加了确切的数量)。这是第二个问题的基础。
UPDATE: Here's http://www.cs.tut.fi/lintula/manual/java/tutorial/uiswing/painting/overview.html我读过的东西:
另外,当 GUI 被另一个窗口覆盖然后变成
如果没有发现,绘画系统会调用paintComponent方法
绘画面积等于新未覆盖的面积。
我的问题是:
(1) 为什么可能paintComponent()
被如此多地称为没有repaint()
?或者,类似的问题,什么可能调用paintComponent()?
更新:做了一些数学计算后,我坚信每个组件(所有按钮和面板)都会不断调用它。但仍然没有调用 repaint()...
(2) 为什么图像会部分加载,直到我从 JFrame 窗口获得焦点?
请注意,我尝试了很多事情:(a)创建自己的双缓冲区并且不使用双缓冲区(我知道它主要用于动画),(b)覆盖和不覆盖paintComponent()
,(c) 绘制和不绘制图像(矩形仍然需要时间来加载),(d) 绝对确保没有repaint()
, (e) 使用和不使用SwingUtilities.invokeLater(new Runnable() {
public void run() { //stuff});
,(f)做了一个if
语句仅 setVisible(true) 一次。
如果必须的话,我可以尝试通过 SSCCE,但我确实认为这些更抽象。谢谢!