1

私は自分の Mac で Java アプリケーションを開発しています。ロジックは次のとおりです。

  1. サーバーがクライアント アプリケーションに、基本的な形状を描画するためのいくつかの命令を送信します。
  2. クライアント アプリケーションは、基本的な形状を Jpanel に描画します。

Shape が到着するたびに、プログラムは repaint() を呼び出します。

 public void paintShape(Shape p) 
{
    //this.paintComponent(this.getGraphics());
   arrayofShapes.add(p);
   this.repaint();
    //this.updateUI();
    //this.update(this.getGraphics());

}
public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g);
    g2d = (Graphics2D) g.create();
    g2d.setStroke(new BasicStroke(2));
    g2d.setColor(pickedColor);
    for(final Shape p : arrayofShapes)
    {
        g2d.draw(p);
    }
    //g2d.dispose();

}

すべてがスムーズに (リアルタイムで) 動作するので、同じアプリケーションを Windows コンピューターでテストすることにしました。その結果、アプリケーションが遅延します。以上が私がたどり着いた結論です。

  • RepaintManager は repaint() 呼び出しを蓄積しています。形状が目的地に到着する様子はわかりますが、場合によっては 5 回以上の再描画呼び出しが 1 つに蓄積され、アプリケーションが非常に遅れたり、リアルタイムではなくなります。

形状が到着するたびに再描画を呼び出す代わりに、タイマーで数ミリ秒ごとに再描画を試みましたが、結果は同じです。コード :

ActionListener listener = new ActionListener(){
          public void actionPerformed(ActionEvent event){
            repaint();
          }
        };

Timer displayTimer = new Timer(5, listener);
displayTimer.start();

さらに、マウスでペイントできるランダムなコードをいくつかテストしました。これは、paintComponent を使用したロジックと同じです。この場合、ラグ感なくスムーズに動作します....例: http://javagraphics.blogspot.com.es/2010/06/shapes-implementing-freehand-pencil.html

私の Windows コンピュータ (同じ Jar) で paintComponent が非常に遅い理由がわかりません。プログラムのパフォーマンスに影響を与える可能性のあるものは何ですか?

ペイント コンポーネントに関するすべての回答を読みましたが、いずれもこの問題を解決しました。

問題を解決し、実際にリアルタイムでアーカイブする方法について何かアドバイスはありますか?

前もって感謝します

ビデオの更新:

Mac ビデオ: https://youtu.be/OhNXdGXoQpkリアルタイム 高負荷を処理しても問題ありません

Windows ビデオhttps://youtu.be/yol2miHudZc明らかにラグ

低クオリティで申し訳ありません

BufferedImage を更新します。

BufferedImage を導入した後も、結果はまだ遅い描画アプリケーションです。注文の1つはすべての形状を削除することであるため、別の問題が発生します。次のことを行う必要があるため、複雑さが増します。

 g2d.clearRect(0, 0, screenSize.width, screenSize.height);

HW/OS/Javaバージョン

ウィンドウズ

  • プロセッサー i5-4300u 2.5GHz
  • ラム12GB
  • Java バージョン 1.7.0_71

マック

  • プロセッサー i7 2.9GHz
  • ラム8GB
  • Java バージョン 1.7.0_67

Java VisualVM

ライブ VisualVM のビデオ: https://youtu.be/cRNX4b3rlZk

ラグが発生する理由を説明できる奇妙なことは何も見当たりませんが、私は専門家ではありません(これも低品質で申し訳ありません)

ご回答ありがとうございました

4

3 に答える 3

2

create()毎回新しいグラフィックス コンテキストを作成する必要はありません。にキャストgするだけGraphics2Dです。これは、すべての具体的な実装で安全です。dispose()これにより、作成されたコンテキストを使用する必要もなくなります。hereに記載されているように、後で描画するために重要なコンテキスト変数はすべて保持してください。

public void paintComponent(Graphics g) { 
    super.paintComponent(g);
    g2d = (Graphics2D) g;
    Stroke oldStroke = g2d.getStroke();
    g2d.setStroke(new BasicStroke(2));
    g2d.setColor(pickedColor);
    for(final Shape p : arrayofShapes) {
        g2d.draw(p);
    }
    g2d.setStroke(oldStroke);
}

また、両方のプラットフォームでプロファイルを比較して相違点を探します。参考までに、ここで引用した例では、どちらのプラットフォームでも何百もの図形を含む選択を快適に処理できます。

于 2015-04-03T21:19:03.650 に答える
1

2 日以上のデバッグの後、この問題はpaintComponent() とは何の関係もないことがわかりました。

同じサーバーでランダムな形状を生成する

Windows アプリでは、15 ミリ秒ごとに形状を送信しているため、いくつかの形状が同時に受信されますが、これは不可能です。そのため、形状を累積します (result =lag)。

一方、Mac アプリでは、形状ごとに時間の受信が異なります (結果 = リアルタイム) 。

親切な対応に感謝します。ご迷惑をおかけして申し訳ありません

于 2015-04-04T14:04:04.560 に答える
1

BufferedImage に対して静的な描画を行ってから、paintComponent メソッドで BufferedImage を描画することをお勧めします。

例えば、

private BufferedImage bufferedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_ARGB);

public void paintShape(Shape p) {
    Graphics2D g2 = bufferedImage.createGraphics();
    g2d.setStroke(MY_STROKE); // make this a constant
    g2d.setColor(pickedColor);
    g2d.draw(p);
    g2d.dispose();
    this.repaint();
}

public void paintComponent(Graphics g) { 
    super.paintComponent(g);
    if (bufferedImage != null) {
       g2.drawImage(bufferedImage, 0, 0, null);
    }
    // do dynamic drawing such as drawing of moving sprites here
}
于 2015-04-03T18:06:16.737 に答える