1

如何在 JPanel 中绘制保持不变且不会重新绘制的东西,我正在做一个交通模拟程序,我希望道路只绘制一次,因为它不会改变。谢谢

4

4 回答 4

3

据我所知,不,除非有透明覆盖的技巧。

我看到(并且做过)的大多数图形应用程序只是在每次重绘时重新绘制整个面板。现在,您可以在图形缓冲区中执行一次,然后通过将图形缓冲区复制到 JPanel 来快速绘制整个背景。它应该比调用所有图形基元来绘制道路要快。

或者,像一些 2D 游戏那样,可能绘制一次并更新移动部件,如精灵:它需要擦除精灵使用的旧位置(恢复那里的背景)并在新位置重新绘制精灵。因此,您仍然在图形缓冲区中有道路的副本,但不是每次都重新绘制它,而是只更新一些小部分。可以稍微快一点。

于 2008-11-09T09:51:57.220 回答
3

我不确定您是否真的希望您的道路永远不会被重新粉刷 - 当您的窗口被调整大小时,或者当它在另一个窗口阻碍它之后变得可见时,重新粉刷事件会触发(例如)。如果您的面板从不重新粉刷,那么它看起来会很奇怪。

据我记得,Swing 只会在这些情况下触发适当的绘制事件,所以你应该可以按照通常的方法使用合适的覆盖来继承 JPanel:

public class RoadPanel extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // your drawing code here
    }
}

如果您将道路缓存为图像或其他图形格式(以节省多次计算显示数据)一次绘制一次,这可能会为您节省一些后续绘制时间。

于 2008-11-09T09:54:27.543 回答
3

每次面板被遮挡(即框架最小化/另一个窗口放在顶部)时,都需要重新绘制组件。因此,仅绘制一次不会像您希望的那样工作。为了更有效地绘制不改变的部分,您可以将它们绘制一次到“缓冲区”图像,然后在每次需要重绘面板或组件时仅绘制此缓冲区。

// 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...
}
于 2008-11-09T16:22:01.393 回答
1

我所做的是为某个部分是否需要重绘设置一个布尔值。然后,在该paintComponent()方法中,我可以检查值并重新绘制某些东西,或者不。

protected void paintComponent(Graphics g){
    super.paintComponent(g);
    if (drawRoad) {
        drawRoadMethod(g);
    }
    drawTheRest(g);
}

有点像这样。

于 2008-11-09T15:12:51.550 回答