/* * org.openmicroscopy.shoola.util.ui.JXTaskPaneContainerSingle * *------------------------------------------------------------------------------ * Copyright (C) 2006-2015 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.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.BorderFactory; //Third-party libraries import org.jdesktop.swingx.JXTaskPane; import org.jdesktop.swingx.JXTaskPaneContainer; //Application-internal dependencies /** * A JXTaskPaneContainer allowing no more than a JXTaskPane expanded at the * same time. * * @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 3.0-Beta4 */ public class JXTaskPaneContainerSingle extends JXTaskPaneContainer implements PropertyChangeListener { /** Bound property indicating the selection of a new task pane. */ public static final String SELECTED_TASKPANE_PROPERTY = "selectedTaskPane"; /** The map hosting the <code>JXTaskPane</code>s. */ private Map<JXTaskPane, Integer> panes; /** Flag indicating that a tab pane can or cannot be expanded. */ private boolean expandable; private GridBagLayout layout = new GridBagLayout(); /** Initializes the component. */ private void initialize() { expandable = true; panes = new HashMap<JXTaskPane, Integer>(); setLayout(layout); setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); setBackground(UIUtilities.BACKGROUND); } /** Creates a new instance. */ public JXTaskPaneContainerSingle() { initialize(); } /** * Passes <code>true</code> to allow a component to be expanded, * <code>false</code> otherwise. * * @param expandable The value to set. */ public void setExpandable(boolean expandable) { this.expandable = expandable; } /** * Returns <code>true</code> if one of the <code>JXTaskPane</code>s * is expanded, <code>false</code> otherwise. * * @return See above. */ public boolean hasTaskPaneExpanded() { Component[] comps = getComponents(); if (comps == null) return false; JXTaskPane pane; for (int i = 0; i < comps.length; i++) { if (comps[i] instanceof JXTaskPane) { pane = (JXTaskPane) comps[i]; if (!pane.isCollapsed()) return true; } } return false; } /** * Get the number of task panes currently in expanded state * @return See above */ private int getTaskPaneExpandedCount() { Component[] comps = getComponents(); if (comps == null) return -1; JXTaskPane pane; int count = 0; for (int i = 0; i < comps.length; i++) { if (comps[i] instanceof JXTaskPane) { pane = (JXTaskPane) comps[i]; if (!pane.isCollapsed()) count++; } } return count; } /** * Return the list of JXTaskPanes in the component. * @return See above. */ public List<JXTaskPane> getTaskPanes() { List<JXTaskPane> list = new ArrayList<JXTaskPane>(); Iterator<JXTaskPane> iterator = panes.keySet().iterator(); while(iterator.hasNext()) list.add(iterator.next()); return list; } /** * Overridden to attach listener to the component if it is a * <code>JXTaskPane</code>. * @see JXTaskPaneContainer#add(Component) */ public void add(JXTaskPane component) { component.setAnimated(false); int index = panes.size(); panes.put(component, index); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = index; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1; c.weighty = 0; c.anchor = GridBagConstraints.NORTH; super.add(component, c); component.addPropertyChangeListener( UIUtilities.COLLAPSED_PROPERTY_JXTASKPANE, this); } /** * Reacts to the expansion of <code>JXTaskPane</code>s. * @see PropertyChangeListener#propertyChange(PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { JXTaskPane src = (JXTaskPane) evt.getSource(); if (!expandable) { src.setCollapsed(true); src.setSpecial(false); return; } Container parent = src.getParent(); Component[] comp = parent.getComponents(); Component c; JXTaskPane p; if (src.isCollapsed()) { if (getTaskPaneExpandedCount()<2) return; for (int i = 0; i < comp.length; i++) { c = comp[i]; if (c instanceof JXTaskPane) { p = (JXTaskPane) c; if (p == src) { GridBagConstraints con = layout.getConstraints(p); con.fill = GridBagConstraints.HORIZONTAL; con.weighty = 0; layout.setConstraints(p, con); } } } firePropertyChange(SELECTED_TASKPANE_PROPERTY, null, src); return; } for (int i = 0; i < comp.length; i++) { c = comp[i]; if (c instanceof JXTaskPane) { p = (JXTaskPane) c; if (p != src) { p.setCollapsed(true); p.setSpecial(false); GridBagConstraints con = layout.getConstraints(p); con.fill = GridBagConstraints.HORIZONTAL; con.weighty = 0; layout.setConstraints(p, con); } else { GridBagConstraints con = layout.getConstraints(p); con.fill = GridBagConstraints.BOTH; con.weighty = 1; layout.setConstraints(p, con); } } } src.setSpecial(true); firePropertyChange(SELECTED_TASKPANE_PROPERTY, null, src); } }