このドキュメントでは、不確定進捗バーを実装するために行われた変更について説明します。このバーは、通常の進捗バーと似た外観のGUIコンポーネントであり、通常の進捗バーと同様に、時間のかかる操作が発生していることを示すアニメーションを使用します。ただし通常の進捗バーと異なり、不確定進捗バーは、操作完了までの程度は示しません。このドキュメントには次のセクションがあります。
デフォルトで、いくつかのJProgressBar
コンストラクタの中の1つを使用して作成される各進捗バーは、確定的です。setIndeterminate
メソッドを使用すると、どのようなJProgressBar
不確定進捗バーでも作成できます。
pb.setIndeterminate(true);
不確定進捗バーの表示は、常に動いています。進捗バーを確定的にして現在値を最小値に設定することで、アニメーションを停止し、進捗バーをクリアすることができます。たとえば、
pb.setValue(pb.getMinimum()); pb.setIndeterminate(false);
任意の時点で、確定モードと不確定モードを切り替えることができます。進捗バーが不確定かどうかは、isIndeterminate
メソッドを使用して確認できます。
進捗バーが不確定な場合は、そのモデル(BoundedRangeModel
)が無視されます。ただし、不確定進捗バー用に更新されなかったL&Fがこのモデルを使用する可能性があるため、モデルが存在し、適切なデータを含んでいる必要があります。
進捗バーのアニメーションの速度を開発者が制御できるように、2つの新規UIデフォルトが追加されました。
"ProgressBar.repaintInterval"
"ProgressBar.cycleTime"
「ProgressBar.cycleTime
」UIデフォルトを使用して、ルック・アンド・フィールの実装者やほかの開発者が、アニメーションの各サイクルにかかる時間を、ミリ秒単位で指定します。たとえば、サイクル時間が500の場合は、不確定モードの進捗バーのアニメーションは、秒あたり2回繰り返されます。デフォルトの描画コードは、この値を再ペイントの間隔、ボックスの長さ、およびコンポーネントの内部領域とともに使用し、ボックスが描画されるごとに跳躍する長さを決定します。この値は、再ペイント間隔の偶数倍にする必要があります。たとえば、再ペイントの間隔が100の場合は、有効なサイクル時間は200、1000、1200などであり、100または500ではありません。ユーザーが無効なサイクル時間を指定した場合は、不確定進捗バーのコードによって適切な値になるようにサイクル時間が自動的に増やされます。
再ペイントの間隔とサイクル時間のデフォルトは、次のように設定します。
UIManager.put("ProgressBar.repaintInterval", new Integer(250)); UIManager.put("ProgressBar.cycleTime", new Integer(6000));
再ペイントの間隔とサイクル時間を入手するには、次のようにします。
int interval = UIManager.getInt("ProgressBar.repaintInterval"); int totalTime = UIManager.getInt("ProgressBar.cycleTime");
基本的な実装、JLF、Motif、およびWindows実装では、進捗バーが不確定モードに切り替えられた場合にのみ、これらのデフォルトが確認されます。
プログラマが進捗バーのルック・アンド・フィールを実装するときの役に立つように、次のAPIが BasicProgressBarUI
クラスに追加されました。
ペイント関連のメソッド
protected void paintIndeterminate(Graphics g, JComponent c)
protected void paintDeterminate(Graphics g, JComponent c)
protected Rectangle getBox(Rectangle)
アニメーションの現行フレームのインデックスを設定および取得するメソッド
protected int getAnimationIndex()
protected void setAnimationIndex(int newValue)
protected void incrementAnimationIndex()
カスタムのアニメーション・スレッドを開始または停止するメソッド
protected void startAnimationTimer()
protected void stopAnimationTimer()
従来は進捗バーのペイントをすべて事前に形成したpaint
メソッドは、現在では、進捗バーの不確定性関連のプロパティ値に応じて、すべての描画をpaintDeterminate
またはpaintIndeterminate
に委譲します。進捗バーが不確定モードの場合は、paint
メソッド(したがってpaintIndeterminate
メソッドも)は、再ペイントの間隔(ミリ秒)ごとに実行されます。paintIndeterminate
メソッドは進捗バーをアニメーションの状態に合わせてペイントする必要がありますが、この状態はgetAnimationIndex
メソッドで指定されます。
getBox
メソッドを使用して、実装で跳躍ボックスのペイントをカスタマイズできます。たとえば、MetalProgressBarUI
がそのpaintIndeterminate
メソッド内でgetBox
を呼び出してスーパー・クラスのBasicProgressBarUI
にボックスを描画させ、その後輪郭線をボックスに追加します。getBox
メソッドをオーバーライドすることで、paintIndeterminate
をふたたび実装しなくても、跳躍ボックスのサイズと位置を完全に制御することができます。
paintIndeterminate
またはgetBox
をオーバーライドする場合は、有効な値で正しく循環するように、incrementAnimationIndex
もオーバーライドする必要がある可能性があります。最初の描画を示す値は0です。規定により、2番目の描画が1、3番目の描画が2というように続きます。最後の有効な値は、規定により、アニメーション・サイクル内の総描画数から1を引いたものです。描画総数を判断するには、再ペイントの間隔と、おそらく、コンポーネントのサイズも考慮に入れる必要があります。「規定により」が暗黙に示すように、アニメーションのインデックスは、0がアニメーション・サイクルの始まりを示しているかぎり、希望する意味と値を持つように実装することができます。
提供されたアニメーション・スレッドを使用しない場合は、2つのxxxAnimationTimer
メソッドをオーバーライドする必要があります。これで、定期的にアニメーションのインデックスを増加させ、進捗バー上でrepaint
を呼び出す独自の実装を提供できます。
進捗バーに関する開発作業の間接的な結果として、次の新しいメソッドがSwingUtilities
に追加されました。
public static Rectangle calculateInnerArea(Component c, Rectangle r)
calculateInnerArea
メソッドは、描画するすべてのクラスにとって有用です。このメソッドによって、コンポーネントが描画できる領域、つまりボーダー領域(コンポーネントのイン・セット)を除くコンポーネントのすべての部分を含む四角形(コンポーネントの座標系内)が返されます。
既存のL&Fの不確定進捗バーを変換することは、比較的単純です。既存のL&Fの進捗バーUIがpaint
をオーバーライドしない、またはオーバーライドしてもsuper.paint
を呼び出す場合は、不確定進捗バーが自動的にサポートされます。WindowsProgressBarUI
、MotifProgressBarUI
、およびMetalProgressBarUI
がこれに相当します。
L&Fの進捗バーUIクラスがBasicProgressBarUI
のサブクラスであって、スーパー・クラスを呼び出さなくてもpaint
をオーバーライドする場合は、確定モードが引き続き作用しますが、不確定モードも確定モードと同じように見えます。
既存の描画コードをpaint
メソッドから取出し、新しいpaintDeterminate
メソッドに移す必要があります。不確定なペイントのためのコードは、新しいpaintIndeterminate
メソッドに移す必要があります。結局、上記の作業がすべて可能であれば、super.paint
が呼び出されないかぎり、paint
メソッドをオーバーライドすべきではありません。その理由は、paint
メソッドのBasicProgressBarUI
実装がデフォルトのアニメーション・スレッドを処理して、パフォーマンスと動作を拡張できるからです。
Macのルック・アンド・フィール (これ以上保守が行われないOracleバージョンと、Appleバージョンの両方)は、スーパークラス・バージョンを呼び出さないでpaint
をオーバーライドするルック・アンド・フィールの例です。
不確定なペイントに対するスレッドのスキームがすでにある場合は、startAnimationTimer
およびstopAnimationTimer
をオーバーライドして、そのスキームを使い続けることができます。または、単に独自のスレッド・コードを削除して、提供されたスキームを使うこともできます。
BasicProgressBarUI
クラスには、不確定進捗バーの実装のほとんどが含まれています。描画コードを除けば、実装コードのほとんどは、アニメーション・スレッドを実装するAnimator
と、不確定モードの切替えを待機するPropertyChangeHandler
の、2つのprivate内部クラス内にあります。
Animator
は、SwingのTimer
クラスを使用してデフォルトのアニメーション・スレッドを実装します。Animator
インスタンスは、必要な場合にBasicProgressBarUI.startAnimationTimer
メソッドによって作成されます。このメソッドは、進捗バーが不確定モードに切り替わったときにプロパティ・ハンドラによって呼び出されます。進捗バーが不確定になると、Animator
のタイマーが、再ペイントの間隔(ミリ秒)ごとに1回、アクション・イベントを起動します。Animator
のアクション・イベント・ハンドラが、incrementAnimationIndex
を呼び出し、続いてrepaint
を呼び出します(repaintによりpaintIndeterminate
が実行されます)。再ペイントの間隔は、ProgressBar.repaintInterval
のUIデフォルトで指定されます。これはstartAnimationTimer
でチェックされます。
PropertyChangeHandler
は、自身を進捗バー上のプロパティのリスナーとして登録します。「不確定」なプロパティが検出されると、ハンドラは変更を通知してstopAnimationTimer
またはstartAnimationTimer
のどちらかを呼び出します。
public void
setIndeterminate(boolean newValue)public boolean
isIndeterminate()
javax.swing.plaf.basic.BasicProgressBarUI
内:
protected void
paintIndeterminate(Graphics g, JComponent c)protected void
paintDeterminate(Graphics g, JComponent c)protected int
getAnimationIndex()protected void
setAnimationIndex(int newValue)protected void
incrementAnimationIndex()protected void
startAnimationTimer()protected void
stopAnimationTimer()protected Rectangle
getBox(Rectangle r)
public static Rectangle
calculateInnerArea(JComponent c, Rectangle r)