AWT 画布在手动调整大小时闪烁
出于智力兴趣,您可以使画布在手动调整大小时不闪烁。
public class FlickerAWT extends Canvas {
public static void main(String[] args) {
Frame f = new Frame(str);
//this line change nothing
//JFrame f = new JFrame(str);
f.add(new FlickerAWT());
f.pack();
int frameWidth = f.getWidth();
int frameHeight = f.getHeight();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation(screenSize.width / 2 - frameWidth / 2, screenSize.height / 2 - frameHeight / 2);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
public void windowDeiconified(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
});
}
private Color bgColor; private Color contentColor;
Font f = new Font("Georgia", Font.BOLD, 16);
static String str = "AWT Canvas Resize Flickering";
public FlickerAWT() {
Random r = new Random();
bgColor = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
contentColor = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
}
public Dimension getPreferredSize() {
FontMetrics fm = getFontMetrics(f);
return new Dimension(fm.stringWidth(str) + 20, fm.getHeight() + 10);
}
public void paint(java.awt.Graphics g) {
g.setColor(bgColor);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(contentColor);
g.setFont(f);
FontMetrics fm = g.getFontMetrics(f);
int dx = getWidth() / 2 - (fm.stringWidth(str) / 2);
int dy = getHeight() / 2 + (fm.getHeight() / 2);
g.drawString(str, dx, dy);
}
}
您可以在 Java 编辑器中复制粘贴并运行该示例。
Just out of intellectual interest can you make a Canvas not flicker when doing a manual resize.
public class FlickerAWT extends Canvas {
public static void main(String[] args) {
Frame f = new Frame(str);
//this line change nothing
//JFrame f = new JFrame(str);
f.add(new FlickerAWT());
f.pack();
int frameWidth = f.getWidth();
int frameHeight = f.getHeight();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation(screenSize.width / 2 - frameWidth / 2, screenSize.height / 2 - frameHeight / 2);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
public void windowDeiconified(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
});
}
private Color bgColor; private Color contentColor;
Font f = new Font("Georgia", Font.BOLD, 16);
static String str = "AWT Canvas Resize Flickering";
public FlickerAWT() {
Random r = new Random();
bgColor = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
contentColor = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
}
public Dimension getPreferredSize() {
FontMetrics fm = getFontMetrics(f);
return new Dimension(fm.stringWidth(str) + 20, fm.getHeight() + 10);
}
public void paint(java.awt.Graphics g) {
g.setColor(bgColor);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(contentColor);
g.setFont(f);
FontMetrics fm = g.getFontMetrics(f);
int dx = getWidth() / 2 - (fm.stringWidth(str) / 2);
int dy = getHeight() / 2 + (fm.getHeight() / 2);
g.drawString(str, dx, dy);
}
}
You can copy paste in a Java editor and run the example.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以将其添加到主方法的开头以避免背景闪烁:
You can add this to the beginning of your main method to avoid the background flicker:
我知道这个问题很古老,但在我的搜索过程中出现了,同时我找到了解决方案:
有两个问题:
一方面,java.awt的
update(...)
方法.Container 如下所示:即,它在绘制其子项之前调用
g.clearRect(...)
来擦除当前内容。因此,您需要在视图堆栈中的 java.awt.Container 的每个后代中重写
update(...)
,但尚未这样做,例如:另外,似乎AWT 或 JVM 或任何人(还没有弄清楚这一点)也会清除主窗口的背景,独立于任何容器的更新方法。为了防止这种情况,请遵循@WhiteFang34的建议,并将以下行添加到您的代码中的某处:
仅执行这两件事最终解决了我的闪烁问题...
I know this question is ancient, but it came up during my search and I meanwhile found a solution:
There are two problems:
On the one hand, the
update(...)
method of java.awt.Container looks like the following:I.e. it calls
g.clearRect(...)
to erase the current content before painting its children.Therefore, you need to override
update(...)
in every descendant of java.awt.Container in your view-stack, that doesn't already do so, with something like:Also, it seems that AWT or the JVM or whoever (haven't figured this out yet) also clears the background of the main window, independent of any Container's update-methods. To prevent this, follow @WhiteFang34's suggestion and add the following line to your code somewhere:
Only doing both of these things finally solved my flicker issues...
我认为关键是使用双缓冲,解决这个问题的一种方法是使用默认双缓冲的 Swing:
The key I believe is to use double buffering, and one way to possibly solve this is to use Swing which double buffers by default: