/* * org.openmicroscopy.shoola.util.ui.ClosableTabbedPane * *------------------------------------------------------------------------------ * Copyright (C) 2006-2008 University of Dundee. All rights reserved. * * * This program 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 2 of the License, or * (at your option) any later version. * This program 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.ui; //Java imports import java.awt.Component; import java.awt.Toolkit; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.Icon; import javax.swing.JTabbedPane; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; //Third-party libraries //Application-internal dependencies /** * A tabbed pane handling component with a close button. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $Date: $) * </small> * @since OME3.0 */ public class ClosableTabbedPane extends JTabbedPane implements ChangeListener, PropertyChangeListener { /** Bound property indicating that an element has been closed. */ public static final String CLOSE_TAB_PROPERTY = "closeTab"; /** Creates the customized UI.*/ private void createUI() { ClosableTabbedPaneUI ui = new ClosableTabbedPaneUI(this); setUI(ui); addMouseMotionListener(ui); } /** * Creates an empty <code>TabbedPane</code> with a default * tab placement of <code>JTabbedPane.TOP</code>. */ public ClosableTabbedPane() { this(TOP, WRAP_TAB_LAYOUT); } /** * Creates an empty <code>TabbedPane</code> with the specified tab placement * of either: <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>. * * @param tabPlacement The placement for the tabs relative to the content. */ public ClosableTabbedPane(int tabPlacement) { this(tabPlacement, WRAP_TAB_LAYOUT); } /** * Creates an empty <code>TabbedPane</code> with the specified tab placement * and tab layout policy. Tab placement may be either: * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>. * Tab layout policy may be either: <code>JTabbedPane.WRAP_TAB_LAYOUT</code> * or <code>JTabbedPane.SCROLL_TAB_LAYOUT</code>. * * @param tabPlacement The placement for the tabs relative to the * content. * @param tabLayoutPolicy The policy for laying out tabs when all tabs * will not fit on one run. */ public ClosableTabbedPane(int tabPlacement, int tabLayoutPolicy) { super(tabPlacement, tabLayoutPolicy); createUI(); setFocusable(false); addChangeListener(this); //Since user can change the font while the application is running //add a listener Toolkit tk = Toolkit.getDefaultToolkit(); tk.addPropertyChangeListener(UIUtilities.HINTS_PROPERTY, this); } /** * Removes all components excepted the selected one from the * tabbed pane. */ void removeOthers() { int tabCount = getTabCount(); int index = getSelectedIndex(); while (tabCount-- > 0) { if (index != tabCount) removeTabAt(tabCount); } } /** * Inserts the passed component. * * @param component The component to add. */ public void insertClosableComponent(ClosableTabbedPaneComponent component) { if (component == null) return; insertTab(component.getName(), component.getIcon(), component, component.getDescription(), component.getIndex()); setSelectedComponent(component); } /** * Overridden to remove components from the tab one by one. * @see JTabbedPane#removeAll() */ public void removeAll() { setSelectedIndex(-1); int tabCount = getTabCount(); while (tabCount-- > 0) removeTabAt(tabCount); } /** * Overridden to fire a property change indicating that * component is removed from the tab pane. * @see JTabbedPane#remove(int) */ public void remove(int index) { removeTabAt(index); } /** * Overridden to fire a property change indicating that * component is removed from the tab pane. * @see JTabbedPane#removeTabAt(int) */ public void removeTabAt(int index) { Component c = getComponentAt(index); if (c instanceof ClosableTabbedPaneComponent) { firePropertyChange(CLOSE_TAB_PROPERTY, null, c); } if (ui instanceof ClosableTabbedPaneUI) { ((ClosableTabbedPaneUI) ui).resetDefault(); } else { createUI(); } super.removeTabAt(index); int n = getTabCount(); if (n == 0) return; if (index > n) setSelectedComponent(getComponentAt(n-1)); } /** * Overridden to insert the tab at the end or requests focus on * the added component. * @see JTabbedPane#addTab(String, Icon, Component) */ public void addTab(String title, Icon icon, Component component) { insertTab(title, icon, component, "", getTabCount()); } /** * Overridden to insert the tab at the end or requests focus on * the added component. * @see JTabbedPane#insertTab(String, Icon, Component, String, int) */ public void insertTab(String title, Icon icon, Component component, String tip, int index) { int addIndex = indexOfComponent(component); if (addIndex != -1) { setSelectedComponent(component); return; } if (ui instanceof ClosableTabbedPaneUI) { ((ClosableTabbedPaneUI) ui).resetDefault(); } else { createUI(); } super.insertTab(title, icon, component, tip, getTabCount()); } /** * Overridden to request the focus on the selected component. * @see JTabbedPane#setSelectedComponent(Component) */ public void setSelectedComponent(Component component) { super.setSelectedComponent(component); if (component != null) component.requestFocus(); } /** * Sets the background of the selected tabbed pane. * @see ChangeListener#stateChanged(ChangeEvent) */ public void stateChanged(ChangeEvent e) { setOpaque(true); for (int i = 0; i < getTabCount(); i++) { if (getSelectedIndex() != i) setBackgroundAt(i, getBackground()); } } /** * Reacts to font changes while the application is running. * @see PropertyChangeListener#propertyChange(PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { String name = evt.getPropertyName(); if (UIUtilities.HINTS_PROPERTY.equals(name)) createUI(); } }