从 paintComponent 调用重绘是一个好习惯
Is calling repaint from paintComponent a good practice
对于我们应用程序中的某些 UI 组件,我们覆盖 paintComponent
,在某些情况下 "recursively" 通过调用 repaint
调用自身。我们使用这种方式来实现组件中动画的高刷新率。
例如,我们使用的进度条类似于:
public class SimpleProgressBar extends JPanel {
private boolean inProgress;
....
@Override
protected void paintComponent(Graphics g) {
if (inProgress) {
paintBar(g);
repaint();
} else {
doSomeOtherThings();
}
}
}
这是一个好的做法吗(尤其是在性能/效率/CPU 使用方面)?
repaint
我们的组件使用 Timer
还是后台线程更好?
在极少数情况下,覆盖 paintComponent
是一件好事。您的情况似乎就是其中之一;但是,重要的是要记住,调用 paintComponent
不是你的工作。我的意思是,它是系统的一个办公室,可以决定何时重新绘制某些组件。当您四处拖动屏幕或将另一个屏幕放在您的屏幕上时,这一点尤其明显。话虽如此,很难说您的方法将被调用多少次;其中,很难说什么时候值得使用该实现。
附带说明一下,正如您所说,后台线程很可能不会使它变得更好,众所周知,Swing 不是线程-safe.
希望对你有所帮助,祝你好运!
Is this a good practice (especially in terms of performance / efficiency / CPU usage)?
不,这不是好的做法。从 paintComponent
内部调用 repaint 是不好的做法,因为:
- 几乎不需要这样的高帧率
- 不保证帧率(repaint不直接调用绘画方法,而是尽快调用此组件的绘画方法'(可能不是立即))
- 优先绘制单个组件,不仅会导致该组件的绘制性能不佳,还会导致其他组件的绘制以及响应其他 EDT 特定任务(例如事件)
Is it better to use a Timer or a background thread to repaint our components?
是的,使用 Timer
或 Thread
可以更好地控制帧速率,而不会在这样做时拖慢 EDT。根据上下文,Timer
在 EDT 上运行(而不是线程),因此不需要分派到 EDT。
对于我们应用程序中的某些 UI 组件,我们覆盖 paintComponent
,在某些情况下 "recursively" 通过调用 repaint
调用自身。我们使用这种方式来实现组件中动画的高刷新率。
例如,我们使用的进度条类似于:
public class SimpleProgressBar extends JPanel {
private boolean inProgress;
....
@Override
protected void paintComponent(Graphics g) {
if (inProgress) {
paintBar(g);
repaint();
} else {
doSomeOtherThings();
}
}
}
这是一个好的做法吗(尤其是在性能/效率/CPU 使用方面)?
repaint
我们的组件使用 Timer
还是后台线程更好?
在极少数情况下,覆盖 paintComponent
是一件好事。您的情况似乎就是其中之一;但是,重要的是要记住,调用 paintComponent
不是你的工作。我的意思是,它是系统的一个办公室,可以决定何时重新绘制某些组件。当您四处拖动屏幕或将另一个屏幕放在您的屏幕上时,这一点尤其明显。话虽如此,很难说您的方法将被调用多少次;其中,很难说什么时候值得使用该实现。
附带说明一下,正如您所说,后台线程很可能不会使它变得更好,众所周知,Swing 不是线程-safe.
希望对你有所帮助,祝你好运!
Is this a good practice (especially in terms of performance / efficiency / CPU usage)?
不,这不是好的做法。从 paintComponent
内部调用 repaint 是不好的做法,因为:
- 几乎不需要这样的高帧率
- 不保证帧率(repaint不直接调用绘画方法,而是尽快调用此组件的绘画方法'(可能不是立即))
- 优先绘制单个组件,不仅会导致该组件的绘制性能不佳,还会导致其他组件的绘制以及响应其他 EDT 特定任务(例如事件)
Is it better to use a Timer or a background thread to repaint our components?
是的,使用 Timer
或 Thread
可以更好地控制帧速率,而不会在这样做时拖慢 EDT。根据上下文,Timer
在 EDT 上运行(而不是线程),因此不需要分派到 EDT。