Не удержался от забавы: оказалось, что можно немного настроить JXTaskPaneContainer (в SwingX), чтобы он вел себя как аккордеон. Все, что для этого нужно, - это заставить не более одного из содержащихся в нем JXTaskPaneContainers. Что-то вроде фрагмента кода:
JXTaskPaneContainer container = new JXTaskPaneContainer() {
private JXTaskPane current;
private PropertyChangeListener expansionListener;
/**
* @inherited <p>
*/
@Override
protected void addImpl(Component comp, Object constraints, int index) {
super.addImpl(comp, constraints, index);
if (comp instanceof JXTaskPane) {
grabExpansionControl((JXTaskPane) comp);
}
}
private void grabExpansionControl(JXTaskPane comp) {
if (current != null) {
comp.setCollapsed(true);
} else {
current = comp;
comp.setCollapsed(false);
}
comp.addPropertyChangeListener("collapsed",
getExpansionListener());
}
private void updateCurrentTaskPane(JXTaskPane source) {
if (source != current) {
if (!source.isCollapsed()) {
if (current != null) {
current.setCollapsed(true);
}
current = source;
}
}
}
private PropertyChangeListener createExpansionListener() {
PropertyChangeListener l = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
// TODO Auto-generated method stub
updateCurrentTaskPane((JXTaskPane) evt.getSource());
}
};
return l;
}
private PropertyChangeListener getExpansionListener() {
if (expansionListener == null) {
expansionListener = createExpansionListener();
}
return expansionListener;
}
};
((VerticalLayout) container.getLayout()).setGap(0);