Author: mkirby
Date: 2012-01-30 14:07:39 -0800 (Mon, 30 Jan 2012)
New Revision: 28157
Added:
core3/api/trunk/swing-util-api/src/main/java/org/cytoscape/util/swing/BasicCollapsiblePanel.java
core3/api/trunk/swing-util-api/src/main/resources/images/
core3/api/trunk/swing-util-api/src/main/resources/images/arrow_collapsed.png
core3/api/trunk/swing-util-api/src/main/resources/images/arrow_expanded.png
Log:
fixes #592 Added class BasicCollapsiblePanel to swing-util-api.
Added:
core3/api/trunk/swing-util-api/src/main/java/org/cytoscape/util/swing/BasicCollapsiblePanel.java
===================================================================
---
core3/api/trunk/swing-util-api/src/main/java/org/cytoscape/util/swing/BasicCollapsiblePanel.java
(rev 0)
+++
core3/api/trunk/swing-util-api/src/main/java/org/cytoscape/util/swing/BasicCollapsiblePanel.java
2012-01-30 22:07:39 UTC (rev 28157)
@@ -0,0 +1,433 @@
+package org.cytoscape.util.swing;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.TitledBorder;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.net.URL;
+
+/**
+ * * Copyright (c) 2004 Memorial Sloan-Kettering Cancer Center
+ * *
+ * * Code written by: Gary Bader
+ * * Authors: Gary Bader, Ethan Cerami, Chris Sander
+ * *
+ * * This library is free software; you can redistribute it and/or modify it
+ * * under the terms of the GNU Lesser General Public License as published
+ * * by the Free Software Foundation; either version 2.1 of the License, or
+ * * any later version.
+ * *
+ * * This library 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. The software and
+ * * documentation provided hereunder is on an "as is" basis, and
+ * * Memorial Sloan-Kettering Cancer Center
+ * * has no obligations to provide maintenance, support,
+ * * updates, enhancements or modifications. In no event shall the
+ * * Memorial Sloan-Kettering Cancer Center
+ * * be liable to any party for direct, indirect, special,
+ * * incidental or consequential damages, including lost profits, arising
+ * * out of the use of this software and its documentation, even if
+ * * Memorial Sloan-Kettering Cancer Center
+ * * has been advised of the possibility of such damage. See
+ * * the GNU Lesser General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU Lesser General Public License
+ * * along with this library; if not, write to the Free Software Foundation,
+ * * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * User: Vuk Pavlovic
+ * Date: Nov 29, 2006
+ * Time: 5:34:46 PM
+ * Description: The user-triggered collapsible panel containing the component
(trigger) in the titled border
+ *
+ *
+ * Updated by: Gregory Hannum
+ * June 7, 2010
+ * Added override for setToolTipText(String text), applying the tip to the
titleComponent so that the tool-tip is visible on the entire component.
+ */
+
+/**
+ * A user-triggered collapsible panel containing the component (trigger) in
the titled border
+ */
+public class BasicCollapsiblePanel extends JPanel {
+ private static final long serialVersionUID = 2010434345567315524L;
+ //Border
+ CollapsableTitledBorder border; // includes upper left component and line
type
+ Border collapsedBorderLine = BorderFactory.createEmptyBorder(2, 2, 2, 2);
// no border
+ Border expandedBorderLine = null; // because this is null, default is
used, etched lowered border on MAC
+
+ //Title
+ AbstractButton titleComponent; // displayed in the titled border
+
+ //Expand/Collapse button
+ final static int COLLAPSED = 0, EXPANDED = 1; // image States
+ ImageIcon[] iconArrow = createExpandAndCollapseIcon();
+ JButton arrow = createArrowButton();
+
+ //Content Pane
+ JPanel panel;
+
+ //Container State
+ boolean collapsed; // stores curent state of the collapsable panel
+
+ /**
+ * Constructor for an option button controlled collapsible panel.
+ * This is useful when a group of options each have unique sub contents.
The radio buttons should be created,
+ * grouped, and then used to construct their own collapsible panels. This
way choosing a different option in
+ * the same option group will collapse all unselected options. Expanded
panels draw a border around the
+ * contents and through the radio button in the fashion of a titled border.
+ *
+ * @param component Radio button that expands and collapses the panel
based on if it is selected or not
+ */
+ public BasicCollapsiblePanel(JRadioButton component) {
+ component.addItemListener(new
BasicCollapsiblePanel.ExpandAndCollapseAction());
+ titleComponent = component;
+ collapsed = !component.isSelected();
+ commonConstructor();
+ }
+
+ /**
+ * Constructor for a label/button controlled collapsible panel. Displays a
clickable title that resembles a
+ * native titled border except for an arrow on the right side indicating
an expandable panel. The actual border
+ * only appears when the panel is expanded.
+ *
+ * @param text Title of the collapsible panel in string format, used to
create a button with text and an arrow icon
+ */
+ public BasicCollapsiblePanel(String text) {
+ arrow.setText(text);
+ titleComponent = arrow;
+ collapsed = true;
+ commonConstructor();
+ }
+
+ /**
+ * Sets layout, creates the content panel and adds it and the title
component to the container,
+ * all constructors have this procedure in common.
+ */
+ private void commonConstructor () {
+ setLayout(new BorderLayout());
+
+ panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+
+ add(titleComponent, BorderLayout.CENTER);
+ add(panel, BorderLayout.CENTER);
+ setCollapsed(collapsed);
+
+ placeTitleComponent();
+ }
+
+ /**
+ * Sets the bounds of the border title component so that it is properly
positioned.
+ */
+ private void placeTitleComponent() {
+ Insets insets = this.getInsets();
+ Rectangle containerRectangle = this.getBounds();
+ Rectangle componentRectangle =
border.getComponentRect(containerRectangle, insets);
+ titleComponent.setBounds(componentRectangle);
+ }
+
+ /** Sets the title of of the border title component.
+ *
+ * @param text The string title.
+ */
+ public void setTitleComponentText(String text) {
+ if (titleComponent instanceof JButton) {
+ titleComponent.setText(text);
+ }
+ placeTitleComponent();
+ }
+
+ /**
+ * This class requires that all content be placed within a designated
panel, this method returns that panel.
+ *
+ * @return panel The content panel.
+ */
+ public JPanel getContentPane() {
+ return panel;
+ }
+
+ /**
+ * This method will not add components as might be expected, instead use
the method getContentPane() which
+ * will return a panel, and you may use add() on that. This is true for
all similar add() methods.
+ */
+ public Component add(Component c) {
+ return super.add(c);
+ }
+
+ /**
+ * Collapses or expands the panel. This is done by adding or removing the
content pane,
+ * alternating between a frame and empty border, and changing the title
arrow.
+ * Also, the current state is stored in the collapsed boolean.
+ *
+ * @param collapse When set to true, the panel is collapsed, else it is
expanded
+ */
+ public void setCollapsed(boolean collapse) {
+ if (collapse) {
+ //collapse the panel, remove content and set border to empty border
+ remove(panel);
+ arrow.setIcon(iconArrow[COLLAPSED]);
+ border = new CollapsableTitledBorder(collapsedBorderLine,
titleComponent);
+ } else {
+ //expand the panel, add content and set border to titled border
+ add(panel, BorderLayout.NORTH);
+ arrow.setIcon(iconArrow[EXPANDED]);
+ border = new CollapsableTitledBorder(expandedBorderLine,
titleComponent);
+ }
+ setBorder(border);
+ collapsed = collapse;
+ updateUI();
+ }
+
+ /**
+ * Returns the current state of the panel, collapsed (true) or expanded
(false).
+ *
+ * @return collapsed Returns true if the panel is collapsed and false if
it is expanded
+ */
+ public boolean isCollapsed() {
+ return collapsed;
+ }
+
+ /**
+ * Returns an ImageIcon array with arrow images used for the different
states of the panel.
+ *
+ * @return iconArrow An ImageIcon array holding the collapse and expanded
versions of the right hand side arrow
+ */
+ private ImageIcon[] createExpandAndCollapseIcon () {
+ ImageIcon[] iconArrow = new ImageIcon[2];
+ URL iconURL;
+
+ iconURL = getClass().getResource("/images/arrow_collapsed.png");
+
+ if (iconURL != null) {
+ iconArrow[COLLAPSED] = new ImageIcon(iconURL);
+ }
+ iconURL = getClass().getResource("/images/arrow_expanded.png");
+
+ if (iconURL != null) {
+ iconArrow[EXPANDED] = new ImageIcon(iconURL);
+ }
+ return iconArrow;
+ }
+
+ /**
+ * Returns a button with an arrow icon and a collapse/expand action
listener.
+ *
+ * @return button Button which is used in the titled border component
+ */
+ private JButton createArrowButton () {
+ JButton button = new JButton("arrow", iconArrow[COLLAPSED]);
+ button.setBorder(BorderFactory.createEmptyBorder(0,1,5,1));
+ button.setVerticalTextPosition(AbstractButton.CENTER);
+ button.setHorizontalTextPosition(AbstractButton.LEFT);
+ button.setMargin(new Insets(0,0,3,0));
+
+ //We want to use the same font as those in the titled border font
+ Font font = BorderFactory.createTitledBorder("Sample").getTitleFont();
+ Color color =
BorderFactory.createTitledBorder("Sample").getTitleColor();
+ button.setFont(font);
+ button.setForeground(color);
+ button.setFocusable(false);
+ button.setContentAreaFilled(false);
+
+ button.addActionListener(new
BasicCollapsiblePanel.ExpandAndCollapseAction());
+
+ return button;
+ }
+
+ /**
+ * Handles expanding and collapsing of extra content on the user's click
of the titledBorder component.
+ */
+ private class ExpandAndCollapseAction extends AbstractAction implements
ActionListener, ItemListener {
+ private static final long serialVersionUID =
2010434345567315525L;
+ public void actionPerformed(ActionEvent e) {
+ setCollapsed(!isCollapsed());
+ }
+ public void itemStateChanged(ItemEvent e) {
+ setCollapsed(!isCollapsed());
+ }
+ }
+
+ /**
+ * Special titled border that includes a component in the title area
+ */
+ private class CollapsableTitledBorder extends TitledBorder {
+ private static final long serialVersionUID =
2010434345567315526L;
+ JComponent component;
+ //Border border;
+
+ public CollapsableTitledBorder(JComponent component) {
+ this(null, component, LEFT, TOP);
+ }
+
+ public CollapsableTitledBorder(Border border) {
+ this(border, null, LEFT, TOP);
+ }
+
+ public CollapsableTitledBorder(Border border, JComponent component) {
+ this(border, component, LEFT, TOP);
+ }
+
+ public CollapsableTitledBorder(Border border, JComponent component,
int titleJustification, int titlePosition) {
+ //TitledBorder needs border, title, justification, position, font,
and color
+ super(border, null, titleJustification, titlePosition, null, null);
+ this.component = component;
+ if (border == null) {
+ this.border = super.getBorder();
+ }
+ }
+
+ public void paintBorder(Component c, Graphics g, int x, int y, int
width, int height) {
+ Rectangle borderR = new Rectangle(x + EDGE_SPACING, y +
EDGE_SPACING, width - (EDGE_SPACING * 2), height - (EDGE_SPACING * 2));
+ Insets borderInsets;
+ if (border != null) {
+ borderInsets = border.getBorderInsets(c);
+ } else {
+ borderInsets = new Insets(0, 0, 0, 0);
+ }
+
+ Rectangle rect = new Rectangle(x, y, width, height);
+ Insets insets = getBorderInsets(c);
+ Rectangle compR = getComponentRect(rect, insets);
+ int diff;
+ switch (titlePosition) {
+ case ABOVE_TOP:
+ diff = compR.height + TEXT_SPACING;
+ borderR.y += diff;
+ borderR.height -= diff;
+ break;
+ case TOP:
+ case DEFAULT_POSITION:
+ diff = insets.top / 2 - borderInsets.top - EDGE_SPACING;
+ borderR.y += diff;
+ borderR.height -= diff;
+ break;
+ case BELOW_TOP:
+ case ABOVE_BOTTOM:
+ break;
+ case BOTTOM:
+ diff = insets.bottom / 2 - borderInsets.bottom -
EDGE_SPACING;
+ borderR.height -= diff;
+ break;
+ case BELOW_BOTTOM:
+ diff = compR.height + TEXT_SPACING;
+ borderR.height -= diff;
+ break;
+ }
+ border.paintBorder(c, g, borderR.x, borderR.y, borderR.width,
borderR.height);
+ Color col = g.getColor();
+ g.setColor(c.getBackground());
+ g.fillRect(compR.x, compR.y, compR.width, compR.height);
+ g.setColor(col);
+ }
+
+ public Insets getBorderInsets(Component c, Insets insets) {
+ Insets borderInsets;
+ if (border != null) {
+ borderInsets = border.getBorderInsets(c);
+ } else {
+ borderInsets = new Insets(0, 0, 0, 0);
+ }
+ insets.top = EDGE_SPACING + TEXT_SPACING + borderInsets.top;
+ insets.right = EDGE_SPACING + TEXT_SPACING + borderInsets.right;
+ insets.bottom = EDGE_SPACING + TEXT_SPACING + borderInsets.bottom;
+ insets.left = EDGE_SPACING + TEXT_SPACING + borderInsets.left;
+
+ if (c == null || component == null) {
+ return insets;
+ }
+
+ int compHeight = component.getPreferredSize().height;
+
+ switch (titlePosition) {
+ case ABOVE_TOP:
+ insets.top += compHeight + TEXT_SPACING;
+ break;
+ case TOP:
+ case DEFAULT_POSITION:
+ insets.top += Math.max(compHeight, borderInsets.top) -
borderInsets.top;
+ break;
+ case BELOW_TOP:
+ insets.top += compHeight + TEXT_SPACING;
+ break;
+ case ABOVE_BOTTOM:
+ insets.bottom += compHeight + TEXT_SPACING;
+ break;
+ case BOTTOM:
+ insets.bottom += Math.max(compHeight, borderInsets.bottom)
- borderInsets.bottom;
+ break;
+ case BELOW_BOTTOM:
+ insets.bottom += compHeight + TEXT_SPACING;
+ break;
+ }
+ return insets;
+ }
+
+ public JComponent getTitleComponent() {
+ return component;
+ }
+
+ public void setTitleComponent(JComponent component) {
+ this.component = component;
+ }
+
+ public Rectangle getComponentRect(Rectangle rect, Insets borderInsets)
{
+ Dimension compD = component.getPreferredSize();
+ Rectangle compR = new Rectangle(0, 0, compD.width, compD.height);
+ switch (titlePosition) {
+ case ABOVE_TOP:
+ compR.y = EDGE_SPACING;
+ break;
+ case TOP:
+ case DEFAULT_POSITION:
+ if (titleComponent instanceof JButton) {
+ compR.y = EDGE_SPACING + (borderInsets.top -
EDGE_SPACING - TEXT_SPACING - compD.height) / 2;
+ } else if (titleComponent instanceof JRadioButton) {
+ compR.y = (borderInsets.top - EDGE_SPACING -
TEXT_SPACING - compD.height) / 2;
+ }
+ break;
+ case BELOW_TOP:
+ compR.y = borderInsets.top - compD.height - TEXT_SPACING;
+ break;
+ case ABOVE_BOTTOM:
+ compR.y = rect.height - borderInsets.bottom + TEXT_SPACING;
+ break;
+ case BOTTOM:
+ compR.y = rect.height - borderInsets.bottom + TEXT_SPACING
+ (borderInsets.bottom - EDGE_SPACING - TEXT_SPACING - compD.height) / 2;
+ break;
+ case BELOW_BOTTOM:
+ compR.y = rect.height - compD.height - EDGE_SPACING;
+ break;
+ }
+ switch (titleJustification) {
+ case LEFT:
+ case DEFAULT_JUSTIFICATION:
+ //compR.x = TEXT_INSET_H + borderInsets.left;
+ compR.x = TEXT_INSET_H + borderInsets.left - EDGE_SPACING;
+ break;
+ case RIGHT:
+ compR.x = rect.width - borderInsets.right - TEXT_INSET_H -
compR.width;
+ break;
+ case CENTER:
+ compR.x = (rect.width - compR.width) / 2;
+ break;
+ }
+ return compR;
+ }
+ }
+
+ /** Sets the tooltip text of this BasicCollapsiblePanel.
+ * @param The string to set as the tooltip.
+ */
+ public void setToolTipText(String text)
+ {
+ super.setToolTipText(text);
+ titleComponent.setToolTipText(text);
+ }
+}
Added:
core3/api/trunk/swing-util-api/src/main/resources/images/arrow_collapsed.png
===================================================================
(Binary files differ)
Property changes on:
core3/api/trunk/swing-util-api/src/main/resources/images/arrow_collapsed.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added:
core3/api/trunk/swing-util-api/src/main/resources/images/arrow_expanded.png
===================================================================
(Binary files differ)
Property changes on:
core3/api/trunk/swing-util-api/src/main/resources/images/arrow_expanded.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
--
You received this message because you are subscribed to the Google Groups
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/cytoscape-cvs?hl=en.