【问题标题】:Custom JPanel Class, paintComponent is Being Spammed自定义 JPanel 类,paintComponent 正在发送垃圾邮件
【发布时间】:2012-03-17 09:12:25
【问题描述】:

我在使用自定义 JPanel 类时遇到问题。我有一台联网相机,我使用 HttpURLConnection 和 JPEGDecoder 接收图像。然后使用 Graphic.drawImage 显示这些图像。出于调试目的,相机设置为 1 fps。

这个 JPanel 类包含在一个 JFrame 中,我还有另一个包含 NASA WorldWind 的 JFrame。显示来自相机的图片时,我的 WorldWind 地图没有响应,并且在调整大小时不会重新绘制。我相信这是因为我在自定义 JPanel 中的paintComponent 被发送了垃圾邮件。

我不明白为什么这么多调用我的 JPanel 的paintComponent,并阻止我的 WorldWind Frame 更新。

自定义 JPanel 类的简介如下:


public class ActiCamera extends JPanel implements Runnable
{
  private String mjpgURL;
  private DataInputStream dis;

  public ActiCamera(String ip)
  {
    mjpgURL = "http://" + ip + "/cgi-bin/cmd/encoder?GET_STREAM";
  }

  public void connect()
  {
    URL u = new URL(mjpgURL);
    ...
    dis = new DataInputStream(from buffered input stream from HttpURLConnection);
  }

  public void start()
  {
    appletThread = new Thread(this);
    appletThread.start();
  }

  public void run()
  {
    connect();
    GetImages();
  }

  public void GetImages()
  {
    while(true)
    {
       //This blocks, executes at 1Hz
       JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(dis);
       image = decoder.decodeAsBufferedImage();
    }
  }

  public void paintComponent(Graphics g)
  {
    super.paintComponent(g);
    if(image != null)
      g.drawImage(image.getScaledInstance(getWidth(), getHeight(), Image.SCALE_DEFAULT), 0, 0, this);
  }

  public static void main(String [] args)
  {
    JFrame jframe = new JFrame();
    ActiCamera my_panel = new ActiCamera("1.1.1.1");
    my_panel.start();
    jframe.getContentPane().add(my_panel);
    jframe.setVisible(true);
  }
}

注意,我不会在任何地方调用 repaint() 或强制绘制。但是,如果我在我的绘画组件类中打印出来,它会以比 1 Hz 快得多的速度发送垃圾邮件。我完全不知道发生了什么。

附: - 我确实意识到我需要paintComponent 和GetImages 之间的互斥体,它们是从不同的线程调用的,但我不认为这会导致问题?

【问题讨论】:

  • GetImages() while 循环中没有 sleep()。什么控制速率?看起来它一直在运行,没有 1 秒的停止。
  • 解码器意味着阻塞读取调用。一旦有图像,它就会返回。

标签: java swing paintcomponent


【解决方案1】:

我找到了答案,我不得不改变我的绘画组件

public void paintComponent(Graphics g)
{
  super.paintComponent(g);
  if(image != null)
    g.drawImage(image, 0, 0, this);
}

我之前的代码 sn-p 中的paintComponent 似乎在某处有一个隐式的paintComponent 调用......也许在(getWidth()getHeight()getScaledInstance()

【讨论】:

    猜你喜欢
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2017-02-09
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 2011-09-17
    相关资源
    最近更新 更多