Как я могу нарисовать что-то на jPanel, которое не будет перекрашиваться? - PullRequest
1 голос
/ 09 ноября 2008

Как я могу нарисовать что-то в JPanel, которое останется прежним и не будет перекрашено, я делаю программу имитации трафика и хочу, чтобы дорога была нарисована один раз, потому что она не изменится. Спасибо

Ответы [ 4 ]

3 голосов
/ 09 ноября 2008

Компонент нужно будет перекрашивать каждый раз, когда панель закрыта (то есть рамка свернута / другое окно расположено сверху). Поэтому рисование чего-либо только один раз не будет работать так, как вы этого хотите. Чтобы сделать детали, которые не изменяются, рисовать более эффективно, вы можете нарисовать их один раз в «буферное» изображение, а затем просто рисовать этот буфер каждый раз, когда необходимо перерисовать панель или компонент.

// 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...
}
3 голосов
/ 09 ноября 2008

Я не уверен, что вы на самом деле хотите, чтобы ваша дорога никогда не перекрашивалась - например, события перерисовки запускаются, когда размер вашего окна изменяется, или когда он становится видимым после другого окна, мешающего ему. Если ваша панель никогда не перерисовывается, она будет выглядеть своеобразно.

Насколько я помню, Swing будет запускать только соответствующие события рисования для этих обстоятельств, поэтому вы должны быть в порядке, следуя обычному методу создания подклассов JPanel с подходящим переопределением:

public class RoadPanel extends JPanel {

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

Если вы кешируете свою дорогу в изображение или другой графический формат (чтобы сохранить вычисление отображаемых данных несколько раз), один раз нарисованный, это может сэкономить вам время на последующих красках.

3 голосов
/ 09 ноября 2008

Насколько мне известно, нет, если только нет хитрости с прозрачными наложениями.

Большинство графических приложений, которые я видел (и делал), просто перерисовывают всю панель на каждом перекрашивании. Теперь вы можете сделать это один раз в графическом буфере, а затем просто быстро закрасить весь фон, скопировав графический буфер в JPanel. Это должно быть быстрее, чем вызывать все графические примитивы для рисования дороги.

Или, как это делают некоторые 2D-игры, возможно, один раз нарисуйте его и обновите движущиеся части, такие как спрайты: нужно стереть старое место, используемое спрайтами (восстановить фон), и заново нарисовать спрайты новое место. Таким образом, у вас все еще есть копия дороги в графическом буфере, но вместо того, чтобы каждый раз перерисовывать ее целиком, вы обновляете только некоторые мелкие детали. Может быть немного быстрее.

1 голос
/ 09 ноября 2008

Что я делаю, так это устанавливаю логическое значение того, нужно ли перерисовывать определенную часть. Затем в методе paintComponent() я могу проверить значение и перерисовать определенную вещь, или нет.

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

Вроде как.

...