Code
class CardLayoutTabbedPane extends JPanel {
private final CardLayout cardLayout = new CardLayout();
private final JPanel tabPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
private final JPanel contentsPanel = new JPanel(cardLayout);
private final JButton hiddenTabs = new JButton("V");
private final ButtonGroup group = new ButtonGroup();
private final JScrollPane tabArea = new JScrollPane(tabPanel) {
@Override public boolean isOptimizedDrawingEnabled() {
return false; // JScrollBar is overlap
}
@Override public void updateUI() {
super.updateUI();
EventQueue.invokeLater(() -> {
getVerticalScrollBar().setUI(new OverlappedScrollBarUI());
getHorizontalScrollBar().setUI(new OverlappedScrollBarUI());
setLayout(new OverlapScrollPaneLayout());
setComponentZOrder(getVerticalScrollBar(), 0);
setComponentZOrder(getHorizontalScrollBar(), 1);
setComponentZOrder(getViewport(), 2);
});
setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
getVerticalScrollBar().setOpaque(false);
getHorizontalScrollBar().setOpaque(false);
setBackground(Color.DARK_GRAY);
setViewportBorder(BorderFactory.createEmptyBorder());
setBorder(BorderFactory.createEmptyBorder());
}
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 18 + 6;
return d;
}
};
protected CardLayoutTabbedPane() {
super(new BorderLayout());
setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
setBackground(new Color(16, 16, 16));
tabPanel.setInheritsPopupMenu(true);
hiddenTabs.setFont(hiddenTabs.getFont().deriveFont(8f));
hiddenTabs.setBorder(BorderFactory.createEmptyBorder(2, 8, 2, 8));
hiddenTabs.setOpaque(false);
hiddenTabs.setFocusable(false);
hiddenTabs.setContentAreaFilled(false);
JPanel header = new JPanel(new BorderLayout());
header.add(new JLayer<>(tabArea, new HorizontalScrollLayerUI()));
header.add(hiddenTabs, BorderLayout.EAST);
add(header, BorderLayout.NORTH);
add(contentsPanel);
}
protected JComponent createTabComponent(String title, Icon icon) {
JToggleButton tab = new TabButton();
tab.setInheritsPopupMenu(true);
group.add(tab);
tab.addMouseListener(new MouseAdapter() {
@Override public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
((AbstractButton) e.getComponent()).setSelected(true);
cardLayout.show(contentsPanel, title);
}
}
});
EventQueue.invokeLater(() -> tab.setSelected(true));
JLabel label = new JLabel(title, icon, SwingConstants.LEADING);
label.setForeground(Color.WHITE);
label.setIcon(icon);
label.setOpaque(false);
JButton close = new JButton(new CloseTabIcon(new Color(0xB0_B0_B0))) {
@Override public Dimension getPreferredSize() {
return new Dimension(12, 12);
}
};
close.addActionListener(e -> System.out.println("close button"));
close.setBorder(BorderFactory.createEmptyBorder());
close.setFocusable(false);
close.setOpaque(false);
// close.setFocusPainted(false);
close.setContentAreaFilled(false);
close.setPressedIcon(new CloseTabIcon(new Color(0xFE_FE_FE)));
close.setRolloverIcon(new CloseTabIcon(new Color(0xA0_A0_A0)));
tab.add(label);
tab.add(close, BorderLayout.EAST);
return tab;
}
public void addTab(String title, Icon icon, Component comp) {
JComponent tab = createTabComponent(title, icon);
tabPanel.add(tab);
contentsPanel.add(comp, title);
cardLayout.show(contentsPanel, title);
EventQueue.invokeLater(() -> tabPanel.scrollRectToVisible(tab.getBounds()));
}
public JScrollPane getTabArea() {
return tabArea;
}
@Override public void doLayout() {
BoundedRangeModel m = tabArea.getHorizontalScrollBar().getModel();
hiddenTabs.setVisible(m.getMaximum() - m.getExtent() > 0);
super.doLayout();
}
}
References