001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.widgets;
003
004import java.awt.Graphics;
005
006import javax.swing.JTabbedPane;
007import javax.swing.plaf.basic.BasicTabbedPaneUI;
008
009/**
010 * A {@link JTabbedPane} extension that completely hides the tab area and border if it contains less than 2 tabs.
011 * @since 17314
012 */
013public class HideableTabbedPane extends JTabbedPane {
014
015    /**
016     * Creates an empty <code>HideableTabbedPane</code> with a default tab placement of <code>JTabbedPane.TOP</code>.
017     * @see #addTab
018     */
019    public HideableTabbedPane() {
020        initUI();
021    }
022
023    /**
024     * Creates an empty <code>HideableTabbedPane</code> with the specified tab placement of either:
025     * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>.
026     *
027     * @param tabPlacement the placement for the tabs relative to the content
028     * @see #addTab
029     */
030    public HideableTabbedPane(int tabPlacement) {
031        super(tabPlacement);
032        initUI();
033    }
034
035    /**
036     * Creates an empty <code>TabbedPane</code> with the specified tab placement and tab layout policy. Tab placement may be either:
037     * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>.
038     * Tab layout policy may be either: <code>JTabbedPane.WRAP_TAB_LAYOUT</code> or <code>JTabbedPane.SCROLL_TAB_LAYOUT</code>.
039     *
040     * @param tabPlacement the placement for the tabs relative to the content
041     * @param tabLayoutPolicy the policy for laying out tabs when all tabs will not fit on one run
042     * @exception IllegalArgumentException if tab placement or tab layout policy are not one of the above supported values
043     * @see #addTab
044     */
045    public HideableTabbedPane(int tabPlacement, int tabLayoutPolicy) {
046        super(tabPlacement, tabLayoutPolicy);
047        initUI();
048    }
049
050    private void initUI() {
051        // See https://stackoverflow.com/a/8897685/2257172
052        setUI(new BasicTabbedPaneUI() {
053            @Override
054            protected int calculateTabAreaHeight(int tabPlacement, int runCount, int maxTabHeight) {
055                return getTabCount() > 1 ? super.calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) : 0;
056            }
057
058            @Override
059            protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
060                if (getTabCount() > 1) {
061                    super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
062                }
063            }
064
065            @Override
066            protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
067                if (getTabCount() > 1) {
068                    super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
069                }
070            }
071
072            @Override
073            protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
074                if (getTabCount() > 1) {
075                    super.paintContentBorder(g, tabPlacement, selectedIndex);
076                }
077            }
078        });
079    }
080}