【发布时间】:2015-05-07 06:42:01
【问题描述】:
我目前正在学习 java,并试图通过 JPanel 在 JFrame 上绘图...
问题是,我的渲染代码正常运行,但我稍微改变了一些东西,现在 repaint() 方法不再刷新 JPanel...
我在每个方法中都有 System.out.println() 调用,但我的控制台看起来像这样:
渲染 使成为 使成为 渲染
,当我调用 render() 方法时。它以前工作过...... 无论如何,这是我的代码。
package Graphics;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Surface extends JPanel {
JFrame frame;
RandomFrame rf;
public Surface(JFrame frame) {
this.frame = frame;
rf = new RandomFrame(frame.getWidth(), frame.getHeight());
}
private void draw(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(Color.blue);
int w = getWidth();
int h = getHeight();
g2d.drawImage(rf.getRandom(w, h), null, 0, 0);
System.out.println("draw");
}
@Override
public void paintComponent(Graphics g) {
System.out.println("paintComponent");
super.paintComponents(g);
draw(g);
}
public void render() {
System.out.println("render");
repaint();
}
}
,而 RandomFrame 返回带有随机数据的 BufferedImage。
【问题讨论】:
-
如果
render输出render到控制台,那么问题可能出在RandomFrame或者您正在更新的Surface实例不是屏幕上的那个.考虑提供一个runnable example 来证明您的问题。这不是代码转储,而是您正在做的事情的一个示例,它突出了您遇到的问题。这将导致更少的混乱和更好的响应 -
您是否可能在事件调度线程中运行的循环中调用
render()?在重绘管理器有机会完成它的工作之前,绘画不会发生,并且在 edt 中循环会阻止它。因此,在这种情况下,只有在从您在 edt 中运行的代码返回后才能完成绘图(并且在无限循环的情况下,永远不会)。 -
尝试在 SwingUtilities 的 invokeLater(..) 调用中调用 repaint()
-
@Terje
repaint是 Swing 中为数不多的线程安全方法之一,它将请求委托给RepaintManager,RepaintManager将事件发布到 EventQueue 上,然后由 EDT 处理... -
请忽略我的评论。这是一个极端情况,整个 gui 都在另一个自定义线程上运行。