私がこれを正確に行ったとき、私はJComponentをサブクラス化しました。Reasonは、波形ビューアコンポーネントであり、実際にはコンテナではありません。レイアウトマネージャーを設定したり、それに子を追加したりすることはありません。子のような特別なコンポーネント(フラグ、注釈など)を使用できますが、Swingコンポーネントのようには機能しない可能性があります。これらの独自のバージョンを使用することに加えて、スイングよりも軽量のコンポーネントを作成するのは本当に簡単です。実際、私はそれらの概念のほとんどを持っていました:1つ以上の選択、ループポイント、フラグ、プレイヘッドなど。
私のコンポーネントは次のように機能しました。
public class AudioView extends JComponent implements Scrollable {
private float samplesPerPixel = 1.0f;
private PlayHeadOverlay playHead;
private List<WaveformOverlay> overlays = new ArrayList<WaveformOverlay>();
private WaveformOverlay selected = null;
protected void paintComponent( Graphics graphics ) {
... // all the math for drawing the waveform
for( WaveformOverlay overlay : overlays ) {
overlay.paint( graphics );
}
}
}
public abstract class WaveformOverlay implements EventDispatcher {
public boolean isVisible() { return visible; }
public void setVisible( visible ) { this.visible = visible; }
public abstract paint( Graphics graphics );
public boolean isWithin(Point point) {
return false; // subclasses override this so we can know if they are inside the overlay (eg mouse events).
}
public String getToolTipText() {
return null; // override this if you want a tooltip upon mouse over
}
}
これは、おおよそ各オーバーレイが実装するものです。イベントのディスパッチ、リスニングなどを処理する方法は他にもいくつかあります。選択、フラグ、再生ヘッド、注釈はすべてWaveformOverlayを実装します。AudioView.paintComponent()メソッド内では、描画の一部が表示ビュー内の各オーバーレイに委任されます。
同じ概念が、マウスモーションイベント、マウスクリックなどにも適用されます。