このドキュメントでは、不確定進捗バーの実装に対して行なった変更について説明します。このバーは、通常の進捗バーと似た外観の GUI コンポーネントであり、通常の進捗バーと同様に、時間のかかる操作が発生していることを示すアニメーションを使用します。ただし通常の進捗バーと異なり、不確定進捗バーは、操作完了までの程度は示しません。このドキュメントには次のセクションがあります。
デフォルトで、いくつかの JProgressBar
コンストラクタの中の 1 つを使用して作成される各進捗バーは、確定的です。setIndeterminate
メソッドを使用すると、どのような JProgressBar
不確定進捗バーでも作成できます。
pb.setIndeterminate(true);
不確定進捗バーの表示は、常に動いています。進捗バーを確定的にして現在値を最小値に設定することで、アニメーションを停止し、進捗バーをクリアすることができます。たとえば、
pb.setValue(pb.getMinimum()); pb.setIndeterminate(false);
任意の時点で、確定モードと不確定モードを切り替えることができます。進捗バーが不確定かどうかは、isIndeterminate
メソッドを使用して確認できます。
進捗バーが不確定な場合は、そのモデル (BoundedRangeModel
) が無視されます。ただし、不確定進捗バー用に更新されなかった Look & Feel がこのモデルを使用する可能性があるため、モデルが存在し、適切なデータを含んでいる必要があります。
進捗バーのアニメーションの速度を開発者が制御できるように、2 つの新規 UI デフォルトが追加されました。
"ProgressBar.repaintInterval"
"ProgressBar.cycleTime"
「ProgressBar.cycleTime
」UI デフォルトを使用して、Look & Feel の実装者やほかの開発者が、アニメーションの各サイクルにかかる時間を、ミリ秒単位で指定します。たとえば、サイクル時間が 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");
Sun から提供される BASIC、JLF、Motif、および Windows 実装では、進捗バーが不確定モードに切り替えられた場合にだけ、これらのデフォルトが確認されます。
プログラマが進捗バーの Look & Feel を実装するときの役に立つように、次の 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
メソッドは、描画するすべてのクラスにとって有用です。このメソッドによって、コンポーネントが描画できる領域、つまりボーダー領域 (コンポーネントのインセット) を除くコンポーネントのすべての部分を含む四角形 (コンポーネントの座標系内) が返されます。
既存の Look & Feel の不確定進捗バーを変換することは、比較的単純です。既存の Look & Feel の進捗バー UI が paint
をオーバーライドしない、またはオーバーライドしても super.paint
を呼び出す場合は、不確定進捗バーが自動的にサポートされます。WindowsProgressBarUI
、MotifProgressBarUI
、および MetalProgressBarUI
がこれに相当します。
Look & Feel の進捗バー UI クラスが BasicProgressBarUI
のサブクラスであって、スーパークラスを呼び出さなくても paint
をオーバーライドする場合は、確定モードが引き続き作用しますが、不確定モードも確定モードと同じように見えます。
既存の描画コードを paint
メソッドから取り出し、新しい paintDeterminate
メソッドに移す必要があります。不確定なペイントのためのコードは、新しい paintIndeterminate
メソッドに移す必要があります。結局、上記の作業がすべて可能であれば、super.paint
が呼び出されないかぎり、paint
メソッドをオーバーライドすべきではありません。その理由は、paint
メソッドの BasicProgressBarUI
実装がデフォルトのアニメーションスレッドを処理して、パフォーマンスと動作を拡張できるからです。
以後メンテナンスされない Sun のバージョンと Apple バージョンの両方の Look & Feel は、スーパークラスを呼び出さないで paint
をオーバーライドする Look & Feel の例です。
不確定なペイントに対するスレッドのスキームがすでにある場合は、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)