如何在 JPanel 中绘制保持不变且不会重新绘制的东西,我正在做一个交通模拟程序,我希望道路只绘制一次,因为它不会改变。谢谢
4 回答
据我所知,不,除非有透明覆盖的技巧。
我看到(并且做过)的大多数图形应用程序只是在每次重绘时重新绘制整个面板。现在,您可以在图形缓冲区中执行一次,然后通过将图形缓冲区复制到 JPanel 来快速绘制整个背景。它应该比调用所有图形基元来绘制道路要快。
或者,像一些 2D 游戏那样,可能绘制一次并更新移动部件,如精灵:它需要擦除精灵使用的旧位置(恢复那里的背景)并在新位置重新绘制精灵。因此,您仍然在图形缓冲区中有道路的副本,但不是每次都重新绘制它,而是只更新一些小部分。可以稍微快一点。
我不确定您是否真的希望您的道路永远不会被重新粉刷 - 当您的窗口被调整大小时,或者当它在另一个窗口阻碍它之后变得可见时,重新粉刷事件会触发(例如)。如果您的面板从不重新粉刷,那么它看起来会很奇怪。
据我记得,Swing 只会在这些情况下触发适当的绘制事件,所以你应该可以按照通常的方法使用合适的覆盖来继承 JPanel:
public class RoadPanel extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// your drawing code here
}
}
如果您将道路缓存为图像或其他图形格式(以节省多次计算显示数据)一次绘制一次,这可能会为您节省一些后续绘制时间。
每次面板被遮挡(即框架最小化/另一个窗口放在顶部)时,都需要重新绘制组件。因此,仅绘制一次不会像您希望的那样工作。为了更有效地绘制不改变的部分,您可以将它们绘制一次到“缓冲区”图像,然后在每次需要重绘面板或组件时仅绘制此缓冲区。
// Field that stores the image so it is always accessible
private Image roadImage = null;
// ...
// ...
// Override paintComponent Method
public void paintComponent(Graphics g){
if (roadImage == null) {
// Create the road image if it doesn't exist
roadImage = createImage(width, height);
// draw the roads to the image
Graphics roadG = roadImage.getGraphics();
// Use roadG like you would any other graphics
// object to draw the roads to an image
} else {
// If the buffer image exists, you just need to draw it.
// Draw the road buffer image
g.drawImage(roadImage, 0, 0, null);
}
// Draw everything else ...
// g.draw...
}
我所做的是为某个部分是否需要重绘设置一个布尔值。然后,在该paintComponent()
方法中,我可以检查值并重新绘制某些东西,或者不。
protected void paintComponent(Graphics g){
super.paintComponent(g);
if (drawRoad) {
drawRoadMethod(g);
}
drawTheRest(g);
}
有点像这样。