Когда я сделал именно это, я подкласс JComponent. Причина в том, что компонент просмотра Waveform действительно не является контейнером. Вы не собираетесь устанавливать менеджер макета или иметь дочерние элементы, которые вы добавляете к нему и т. Д. У вас могут быть специальные компоненты, которые могут быть как дочерние элементы, например, флаги, аннотации и т. Д., Но они, вероятно, не будут действовать как компоненты 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 () метод делегирует часть своего рисунка каждому оверлею в видимом представлении.
Та же концепция применяется для событий движения мыши, щелчков мыши и т. Д.