package org.esa.snap.rcp.util;
import com.bc.ceres.swing.CollapsiblePane;
import org.openide.util.ImageUtilities;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
/**
* @author Norman Fomferra
* @author Tonio Fincke
*/
public class CollapsibleItemsPanel extends JComponent {
private Item[] items;
private JToggleButton[] toggleButtons;
private static ImageIcon COL_ICON = ImageUtilities.loadImageIcon("org/esa/snap/rcp/icons/NodeCollapsed11.png", false);
private static ImageIcon EXP_ICON = ImageUtilities.loadImageIcon("org/esa/snap/rcp/icons/NodeExpanded11.png", false);
private List<CollapseListener> collapseListenerList;
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
// e.printStackTrace();
}
CollapsibleItemsPanel collapsibleItemsPanel = new CollapsibleItemsPanel(createTableItem("Time", 2, 2),
createTableItem("Position", 6, 2),
createTableItem("Bands", 18, 3));
JFrame frame = new JFrame(CollapsiblePane.class.getSimpleName());
frame.getContentPane().add(new JScrollPane(collapsibleItemsPanel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
frame.pack();
frame.setVisible(true);
}
public static Item<JTable> createTableItem(String name, int rows, int columns) {
JTable table = new JTable(rows, columns);
table.setCellSelectionEnabled(false);
table.setColumnSelectionAllowed(false);
table.setRowSelectionAllowed(false);
table.setShowGrid(true);
return new DefaultItem<>(name, table);
}
public CollapsibleItemsPanel(Item... items) {
this.items = items;
this.toggleButtons = new JToggleButton[items.length];
setLayout(null);
collapseListenerList = new ArrayList<>();
for (int i = 0; i < items.length; i++) {
Item item = items[i];
JToggleButton button = new JToggleButton(item.getDisplayName());
Font font = button.getFont();
if (font != null) {
button.setFont(font.deriveFont(Font.PLAIN, font.getSize()));
} else {
button.setFont(new Font(Font.DIALOG, Font.PLAIN, 11));
}
JPanel panel = new JPanel(new BorderLayout(0, 0));
panel.add(button, BorderLayout.NORTH);
panel.add(item.getComponent(), BorderLayout.CENTER);
button.setHorizontalAlignment(SwingConstants.LEFT);
button.setBorder(new EmptyBorder(2, 4, 2, 4));
button.setIcon(EXP_ICON);
final int index = i;
button.addActionListener(e -> {
final boolean expand = !button.isSelected();
item.getComponent().setVisible(expand);
button.setIcon(!expand ? COL_ICON : EXP_ICON);
if (expand) {
notifyExpand(index);
} else {
notifyCollapse(index);
}
});
toggleButtons[i] = button;
add(panel);
}
}
public Item getItem(int index) {
return items[index];
}
public void setCollapsed(int index, boolean collapsed) {
items[index].getComponent().setVisible(!collapsed);
toggleButtons[index].setSelected(collapsed);
toggleButtons[index].setIcon(collapsed ? COL_ICON : EXP_ICON);
}
private void notifyCollapse(int index) {
for (CollapseListener collapseListener : collapseListenerList) {
collapseListener.collapse(index);
}
}
private void notifyExpand(int index) {
for (CollapseListener collapseListener : collapseListenerList) {
collapseListener.expand(index);
}
}
public void addCollapseListener(CollapseListener collapseListener) {
collapseListenerList.add(collapseListener);
}
public void remove(CollapseListener collapseListener) {
collapseListenerList.remove(collapseListener);
}
@Override
public Dimension getPreferredSize() {
int width = 0;
int height = 0;
Component[] components = getComponents();
for (Component component : components) {
Dimension preferredSize = component.getPreferredSize();
width = Math.max(width, preferredSize.width);
height += preferredSize.height;
}
return new Dimension(width, height);
}
@Override
public void doLayout() {
int y = 0;
int width = getWidth();
Component[] components = getComponents();
for (Component component : components) {
Dimension preferredSize = component.getPreferredSize();
component.setBounds(0, y, width, preferredSize.height);
y += preferredSize.height;
}
}
public boolean isCollapsed(int index) {
return !items[index].getComponent().isVisible();
}
public static interface Item<T extends JComponent> {
String getDisplayName();
T getComponent();
}
public static class DefaultItem<T extends JComponent> implements Item<T> {
String displayName;
T component;
public DefaultItem(String displayName, T component) {
this.displayName = displayName;
this.component = component;
}
@Override
public String getDisplayName() {
return displayName;
}
@Override
public T getComponent() {
return component;
}
}
public interface CollapseListener {
void collapse(int index);
void expand(int index);
}
}