/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.gui.component; import icy.gui.component.button.IcyButton; import icy.resource.ResourceUtil; import icy.resource.icon.IcyIcon; import java.awt.Color; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.EventListener; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.SwingConstants; /** * JTabbedPane with close button (configurable) in tab. * * @author Stephane */ public class CloseableTabbedPane extends JTabbedPane { /** * */ private static final long serialVersionUID = 2105647353561738725L; public static interface CloseableTabbedPaneListener extends EventListener { /** * Called when the tab close button has been clicked.<br> * This callback is used to do special actions before tab close.<br> * You can prevent the close operation by returning false. * * @return true if the tab can be closed, false otherwise. */ public boolean tabClosing(int index, String title); /** * Called when the tab has been closed. */ public void tabClosed(int index, String title); } private class CloseableTabComponent extends JPanel { /** * */ private static final long serialVersionUID = 6828288788693627610L; final private IcyButton closeButton; final private JLabel label; final private Component sep; public CloseableTabComponent(String title, Icon icon) { super(); setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS)); setBorder(BorderFactory.createEmptyBorder()); setOpaque(false); label = new JLabel(title, icon, SwingConstants.CENTER); label.setOpaque(false); sep = Box.createHorizontalStrut(6); closeButton = new IcyButton(new IcyIcon(ResourceUtil.ICON_DELETE, 12)); closeButton.setFlat(true); closeButton.setContentAreaFilled(false); closeButton.setToolTipText("close"); closeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionevent) { final int index = indexOfTabComponent(CloseableTabComponent.this); if (index != -1) { if (CloseableTabbedPane.this.fireTabClosing(index, getTitle())) { CloseableTabbedPane.this.removeTabAt(index); CloseableTabbedPane.this.fireTabClosed(index, getTitle()); } } } }); add(label); add(sep); add(closeButton); validate(); } public boolean isClosable() { return closeButton.isVisible(); } public void setClosable(boolean value) { sep.setVisible(value); closeButton.setVisible(value); } public String getTitle() { return label.getText(); } public void setTitle(String title) { label.setText(title); } public void setIcon(Icon icon) { label.setIcon(icon); } public void setDisabledIcon(Icon disabledIcon) { label.setDisabledIcon(disabledIcon); } public void setBackgroundAll(Color background) { label.setBackground(background); closeButton.setBackground(background); } public void setForegroundAll(Color foreground) { label.setForeground(foreground); closeButton.setForeground(foreground); } } /** * {@link JTabbedPane} */ public CloseableTabbedPane() { super(); } /** * {@link JTabbedPane} */ public CloseableTabbedPane(int tabPlacement) { super(tabPlacement); } /** * {@link JTabbedPane} */ public CloseableTabbedPane(int tabPlacement, int tabLayoutPolicy) { super(tabPlacement, tabLayoutPolicy); } /** * Returns the 'closable' state of tab component at <code>index</code>. * * @param index * the tab index where the check state is queried * @return true if tab component at <code>index</code> can be closed (close button visible).<br> * Returns false otherwise * @exception IndexOutOfBoundsException * if index is out of range (index < 0 || index >= tab count) * @see #setTabClosable(int, boolean) */ public boolean isTabClosable(int index) { return ((CloseableTabComponent) getTabComponentAt(index)).isClosable(); } /** * Set the 'closable' state of tab component at <code>index</code>. * * @param index * the tab index we want to set the 'closable' state * @param value * true if the tab should be 'closable' (close button visible), false otherwise. * @exception IndexOutOfBoundsException * if index is out of range (index < 0 || index >= tab count) * @see #isTabClosable(int) */ public void setTabClosable(int index, boolean value) { ((CloseableTabComponent) getTabComponentAt(index)).setClosable(value); } @Override public void setIconAt(int index, Icon icon) { super.setIconAt(index, icon); final CloseableTabComponent comp = (CloseableTabComponent) getTabComponentAt(index); if (comp != null) comp.setIcon(icon); } @Override public void setDisabledIconAt(int index, Icon disabledIcon) { super.setDisabledIconAt(index, disabledIcon); final CloseableTabComponent comp = (CloseableTabComponent) getTabComponentAt(index); if (comp != null) comp.setDisabledIcon(disabledIcon); } @Override public void setBackgroundAt(int index, Color background) { super.setBackgroundAt(index, background); final CloseableTabComponent comp = (CloseableTabComponent) getTabComponentAt(index); if (comp != null) comp.setBackgroundAll(background); } @Override public void setForegroundAt(int index, Color foreground) { super.setForegroundAt(index, foreground); final CloseableTabComponent comp = (CloseableTabComponent) getTabComponentAt(index); if (comp != null) comp.setForegroundAll(foreground); } @Override public void setTitleAt(int index, String title) { super.setTitleAt(index, title); final CloseableTabComponent comp = (CloseableTabComponent) getTabComponentAt(index); if (comp != null) comp.setTitle(title); } @Override public void insertTab(String title, Icon icon, Component component, String tip, int index) { super.insertTab(title, icon, component, tip, index); setTabComponentAt(index, new CloseableTabComponent(title, icon)); } protected void fireTabClosed(int index, String text) { for (CloseableTabbedPaneListener l : listenerList.getListeners(CloseableTabbedPaneListener.class)) l.tabClosed(index, text); } protected boolean fireTabClosing(int index, String text) { for (CloseableTabbedPaneListener l : listenerList.getListeners(CloseableTabbedPaneListener.class)) if (!l.tabClosing(index, text)) return false; return true; } public void addCloseableTabbedPaneListener(CloseableTabbedPaneListener l) { listenerList.add(CloseableTabbedPaneListener.class, l); } public void removeCloseableTabbedPaneListener(CloseableTabbedPaneListener l) { listenerList.remove(CloseableTabbedPaneListener.class, l); } }