All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.weisj.darklaf.components.ClosableTabComponent Maven / Gradle / Ivy

There is a newer version: 3.0.2
Show newest version
/*
 * MIT License
 *
 * Copyright (c) 2021 Jannis Weis
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
package com.github.weisj.darklaf.components;

import java.awt.*;
import java.awt.event.*;
import java.util.function.BiFunction;

import javax.swing.*;
import javax.swing.plaf.ComponentUI;

import com.github.weisj.darklaf.ui.tabbedpane.DarkTabbedPaneUI;

/** @author Jannis Weis */
public class ClosableTabComponent extends JPanel {

    private JTabbedPane pane;
    private final Component component;
    private boolean closable;
    private final CloseButton closeButton;

    public ClosableTabComponent(final JTabbedPane pane) {
        this(pane, null);
    }

    public ClosableTabComponent(final JTabbedPane pane, final Component component) {
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        this.component = component != null ? component : new TabLabel(this);
        if (pane == null) {
            throw new NullPointerException("TabbedPane is null.");
        }
        this.pane = pane;
        closable = true;
        closeButton = new TabCloseButton(this);
        setOpaque(false);
        add(getTabComponent());
        add(getCloseButton());
    }

    public Component getTabComponent() {
        return component;
    }

    public CloseButton getCloseButton() {
        return closeButton;
    }

    public boolean isClosable() {
        return closable;
    }

    public void setClosable(final boolean closable) {
        if (this.closable != closable) {
            this.closable = closable;
            if (!closable) {
                remove(closeButton);
            } else {
                add(closeButton);
            }
            doLayout();
        }
    }

    public void setTabbedPane(final JTabbedPane pane) {
        this.pane = pane;
    }

    public int getIndexInTabbedPane() {
        return pane.indexOfTabComponent(this);
    }

    @Override
    public void setEnabled(final boolean enabled) {
        super.setEnabled(enabled);
        getTabComponent().setEnabled(enabled);
        getCloseButton().setEnabled(enabled);
    }

    protected static class TabLabel extends JLabel {

        private final ClosableTabComponent tabComponent;

        protected TabLabel(final ClosableTabComponent tabComponent) {
            this.tabComponent = tabComponent;
            setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
        }

        protected  T getTabProperty(final BiFunction mapper, final T fallback) {
            if (tabComponent != null) {
                int i = tabComponent.getIndexInTabbedPane();
                if (i != -1) {
                    return mapper.apply(tabComponent.pane, i);
                }
            }
            return fallback;
        }

        @Override
        public Icon getIcon() {
            return getTabProperty(JTabbedPane::getIconAt, null);
        }

        @Override
        public Icon getDisabledIcon() {
            return getTabProperty(JTabbedPane::getDisabledIconAt, null);
        }

        @Override
        public int getDisplayedMnemonic() {
            return getTabProperty(JTabbedPane::getDisplayedMnemonicIndexAt, -1);
        }

        @Override
        public String getText() {
            return getTabProperty(JTabbedPane::getTitleAt, "");
        }
    }

    protected static class TabCloseButton extends CloseButton implements ActionListener {

        private final ClosableTabComponent tabComponent;

        protected TabCloseButton(final ClosableTabComponent tabComponent) {
            this.tabComponent = tabComponent;
            addActionListener(this);
            MouseListener mouseListener = new MouseAdapter() {
                @Override
                public void mouseEntered(final MouseEvent e) {
                    ComponentUI ui = tabComponent.pane.getUI();
                    if (ui instanceof DarkTabbedPaneUI) {
                        int i = tabComponent.pane.indexOfTabComponent(tabComponent);
                        if (i != -1) {
                            ((DarkTabbedPaneUI) ui).setRolloverTab(i);
                            tabComponent.pane.repaint(tabComponent.pane.getBoundsAt(i));
                        }
                    }
                }
            };
            addMouseListener(mouseListener);
            setToolTipText(UIManager.getString("Actions.closableTabbedPane.close", tabComponent.pane.getLocale()));
        }

        @Override
        public void actionPerformed(final ActionEvent e) {
            if ((e.getModifiers() & ActionEvent.ALT_MASK) != 0) {
                // Close all other tabs.
                int tabCount = tabComponent.pane.getTabCount();
                for (int i = tabCount - 1; i >= 0; i--) {
                    Component tabComp = tabComponent.pane.getTabComponentAt(i);
                    if (tabComp == tabComponent) continue;
                    if (tabComp instanceof ClosableTabComponent && ((ClosableTabComponent) tabComp).isClosable()) {
                        tabComponent.pane.removeTabAt(i);
                    }
                }
            } else {
                int i = tabComponent.pane.indexOfTabComponent(tabComponent);
                if (i != -1) {
                    tabComponent.pane.remove(i);
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy