ビューでの描画パフォーマンス

オブジェクト・クラスを慎重に選択したにもかかわらず、描画パフォーマンスが依然として十分でないことが時としてあります。これは、特に複数ビュー内の膨大な数のオブジェクトを表示する場合に起こります。 変更のたびに、各ビューを描画する必要があるので、描画パフォーマンスはボトルネックとなります。一般的に描画パフォーマンスを改善する最善の策は、1 つのビューだけを表示することです。ただし、ごく一般的なシナリオでは、メイン・ビューと概要があります。

再描画セッション

オブジェクトが変更されると、そのオブジェクトを正しく表示するために、必ずビューを再描画する必要があります。多くのオブジェクトが一度に変更される場合、各オブジェクトごとに再描画するのではなく、終了時に 1 回だけ再描画するほうが得策です。これは、再描画セッションで実現できます。
manager.initReDraws();
   try {
      ...many objects change, but redraw is suppressed now ...
   } finally {
     // redraw the views
     manager.reDrawViews();
   }
詳細については、「描画タスクの最適化」を参照してください。

ビューのバッファリング

定義済みのビュー・バッファリング手法の 1 つを使用できます。 バッファーされたビューは、ビュー内に含まれる個別のオブジェクトよりも、速く描画されます。これに対してバッファーの更新は低速になることがあります。したがって、バッファリングは、オブジェクトがまれにしか変更されない場合に適しています。
  • ダブル・バッファリング (setDoubleBuffering) は、ビュー全体をバッファーに入れるために使用する必要があります。最適化されたビュー変換モード (setOptimizedTranslation) でのスクロール・パフォーマンスを改善します。詳細については、「ダブル・バッファリングの管理」を参照してください。
  • トリプル・バッファリング (setTripleBufferedLayerCount) は、ビューの最初の数レイヤーをバッファーに入れるために使用できます。これは、移動オブジェクトを静的背景の前面に描画する場合に有効です。レイヤー 0 から n には背景を入れることができ、レイヤー n+1、n+2 ... には移動オブジェクトを入れることができます。 これにより、全体的な描画パフォーマンスが改善されます。レイヤー 1 から n がバッファー・ビットマップから素早くコピーされるためです。ただし、ビューのサイズ分の余分なメモリー内ビットマップが必要なため、メモリー消費量が増えます。 詳細については、「トリプル・バッファリング・レイヤー」を参照してください。
  • レイヤー・キャッシュ (setLayerCached) は、変更されることがない静的レイヤーが 1 から n の連続した範囲にない場合、同じ理由で使用できます。キャッシュされた各レイヤーには、余分なメモリー内ビットマップが必要です。これは、トリプル・バッファリングと結び付けることができます。つまり静的レイヤーが 0、1、2、3、5、および 7 である場合、レイヤー 0 から 3 にトリプル・バッファリング、レイヤー 5 および 7 にレイヤー・キャッシュを使用します。レイヤー 0 から 3 に個別のレイヤー・キャッシュを使用した場合、トリプル・バッファリングによってこれらのレイヤーを結び付けた場合より、多くのビットマップ・バッファーが必要になります。詳細については、「レイヤーのキャッシュ」を参照してください。

概要の最適化

概要は、一般的にメイン・ビューでナビゲートするために使用される 2 次ビューです。概要は、通常縮小形式でマネージャー全体を表示します。概要は、以下の理由でパフォーマンスのボトルネックとなります。
  • 多くのオブジェクトのすべてに必要になります。
  • マネージャーの内容が変更された場合に、必ずビューに適合する必要があります。
膨大な数のオブジェクトを表示する場合、概要は多くの時間を消費するので、アプリケーションが無反応になります。 その一方、概要の表示は、多くの場合、極端な精度を必要としません。このことは、パフォーマンスの改善のために利用できます。
  • 概要はメイン・ビューほど頻繁に更新を行う必要はありません。再描画スキップ・メカニズム (setRepaintSkipThreshold) を使用して、数秒単位でのみ概要を更新します。
  • 概要の場合は点滅 (setBlinkingMode) を無効にすることを考えます。点滅オブジェクトでは、ビューの定期的な描画が必要になります。これは、表示するオブジェクトの数が多いほど、多くの時間を消費します。
  • 独自のグラフィック・オブジェクトを実装する場合、draw メソッド (draw) を変更して、ビューが縮小されるときに、小さな矩形のみが描画されるようにします。矩形の描画は、ノードを詳細に描画するよりも速くなります。縮小率が大きいと、これらのビューは常に見えなくなります。draw メソッドの入力トランスフォーマーの倍率を調べると、オブジェクトを詳細に描画する必要があるか、矩形として概略的に描画すればよいのかを簡単に判断できます。この手法の例は、コード例 <installdir>/jviews-framework89/codefragments/lighttext に示しています。

不経済な描画

ビューで不経済な描画や些少部分の頻繁的更新があると、低速になります。
不経済な描画とは、オブジェクトの数が多いためや、オブジェクトに高いグラフィック品質 (アンチエイリアシング、階調、テキストなど) が必要なため、ビュー全体を再描画する時間が極めて長いことを意味します。
頻繁的更新とは、1 秒ごとに 10 回以上の更新があることを意味します。
低速性は、デフォルトの Swing RepaintManager が原因である場合があります。デフォルトでは、このマネージャーは、更新する領域を結合して、2 つの個別の小さな矩形ではなく、1 つの大きな矩形を更新しようとします。これは、自身では素早く再描画する GUI においてはヒューリスティックで有用なものであるが、JViews と結合した場合はパフォーマンス上のボトルネックとなることがあります。
Rogue Wave® JViews は、代替の RepaintManager をクラス IlvExpensiveDrawingRepaintManager 内に提供します。これは、より拡張したヒューリスティックを適用して描画領域を決定することで、再描画に必要な時間を著しく削減します。これは、画面上のオブジェクトの平均サイズまたはダイアグラムのタイプを 考慮に入れるようにカスタマイズすることができます。

点滅

Rogue Wave JViews は、点滅オブジェクト、点滅色、および点滅アクションをサポートします (「グラフィック・オブジェクトの点滅」を参照)。点滅するオブジェクトは、定期的に描画する必要があります。以下にパフォーマンスを改善するためのいくつかのヒントを示します。
  • 不要であればどのような点滅も使用しないでください。
  • 点滅オブジェクトがある場合、すべてのオブジェクトが同じ点滅タイミングを使用するようにしてください。この場合、すべてのオブジェクトが同時に描画されます。これにより、異なるオブジェクトを異なる時間で定期的に描画するより効率的になります。
  • 点滅はメイン・ビューでのみ有効にしてください。 概要などの 2 次ビューでは点滅を無効にします。「setBlinkingMode」を参照してください。
  • 点滅アクションでオブジェクトを定期的に任意の方法で変更できますが、これは著しく非効率的になる場合があります。グラフィック・オブジェクトのバウンディング・ボックスを変更する点滅アクションの使用は避けてください。
  • 点滅と組み合わせて IlvExpensiveDrawingRepaintManager を使用することを考慮してください。 点滅では、ビューの領域が定期的に再描画されます。デフォルトの RepaintManager には、再描画を必要とする領域を結合するための単純な戦略があります。IlvExpensiveDrawingRepaintManager には、個別のグラフィック・オブジェクトの再描画が非常に非効率的である場合に最適化された拡張戦略があります。

グリッドおよび背景のパターン

マネージャー・ビューでグリッドが有効になっていると、多くのグラフィック・リソースが消費されます。パフォーマンスを改善するため、ビューでグリッドを有効にしないでください。グリッドを無効にするには、setGrid を呼び出します。
ビューは、背景パターンを持つこともできます。グリッドと同様に、多くのグラフィック・リソースを消費します。背景パターンを無効にするには、setBackgroundPatternLocation を呼び出します。
ビューの背景を同一色だけで描画し、グリッドも背景パターンも使用しなければ、ビューの描画は最も効率的になります。