Coverage Report - org.dishevelled.disclosuretriangle.DisclosureTriangle
 
Classes in this File Line Coverage Branch Coverage Complexity
DisclosureTriangle
100%
69/69
90%
20/22
1.933
DisclosureTriangle$1
100%
5/5
100%
2/2
1.933
 
 1  
 /*
 2  
 
 3  
     dsh-disclosure-triangle  Disclosure triangle container.
 4  
     Copyright (c) 2007-2013 held jointly by the individual authors.
 5  
 
 6  
     This library is free software; you can redistribute it and/or modify it
 7  
     under the terms of the GNU Lesser General Public License as published
 8  
     by the Free Software Foundation; either version 3 of the License, or (at
 9  
     your option) any later version.
 10  
 
 11  
     This library is distributed in the hope that it will be useful, but WITHOUT
 12  
     ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
 13  
     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 14  
     License for more details.
 15  
 
 16  
     You should have received a copy of the GNU Lesser General Public License
 17  
     along with this library;  if not, write to the Free Software Foundation,
 18  
     Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
 19  
 
 20  
     > http://www.fsf.org/licensing/licenses/lgpl.html
 21  
     > http://www.opensource.org/licenses/lgpl-license.php
 22  
 
 23  
 */
 24  
 package org.dishevelled.disclosuretriangle;
 25  
 
 26  
 import java.awt.BorderLayout;
 27  
 import java.awt.Container;
 28  
 import java.awt.Dimension;
 29  
 
 30  
 import java.awt.event.MouseAdapter;
 31  
 import java.awt.event.MouseEvent;
 32  
 
 33  
 import javax.swing.Icon;
 34  
 import javax.swing.JLabel;
 35  
 import javax.swing.JPanel;
 36  
 import javax.swing.RootPaneContainer;
 37  
 import javax.swing.UIManager;
 38  
 
 39  
 /**
 40  
  * Disclosure triangle container.
 41  
  *
 42  
  * @author  Michael Heuer
 43  
  * @version $Revision$ $Date$
 44  
  */
 45  4
 public final class DisclosureTriangle
 46  
     extends JPanel
 47  
 {
 48  
     /** Label. */
 49  
     private final JLabel label;
 50  
 
 51  
     /** Wrapped container. */
 52  
     private final Container container;
 53  
 
 54  
     /** True if this disclosure triangle container is collapsed. */
 55  
     private boolean collapsed;
 56  
 
 57  
     /** Collapse icon. */
 58  
     private Icon collapseIcon;
 59  
 
 60  
     /** Expand icon. */
 61  
     private Icon expandIcon;
 62  
 
 63  
     /** Default label text, <code>"Details"</code>. */
 64  
     public static final String DEFAULT_LABEL_TEXT = "Details";
 65  
 
 66  
 
 67  
     /**
 68  
      * Create a new disclosure triangle container wrapping the specified container.
 69  
      *
 70  
      * <p>
 71  
      * By default this disclosure triangle container will be collapsed, its label text will be
 72  
      * <code>"Details"</code>, its collapse icon will be the icon resource returned by
 73  
      * <code>UIManager.getIcon("Tree.expandedIcon")</code>, and its expand icon will be
 74  
      * the icon resource returned by <code>UIManager.getIcon("Tree.collapsedIcon")</code>.
 75  
      * </p>
 76  
      *
 77  
      * @see #DEFAULT_LABEL_TEXT
 78  
      * @see javax.swing.UIManager#getIcon
 79  
      * @param container container to wrap, must not be null
 80  
      */
 81  
     public DisclosureTriangle(final Container container)
 82  
     {
 83  9
         super();
 84  9
         if (container == null)
 85  
         {
 86  1
             throw new IllegalArgumentException("container must not be null");
 87  
         }
 88  8
         this.container = container;
 89  
 
 90  8
         collapsed = true;
 91  8
         collapseIcon = UIManager.getIcon("Tree.expandedIcon");
 92  8
         expandIcon = UIManager.getIcon("Tree.collapsedIcon");
 93  8
         label = new JLabel(DEFAULT_LABEL_TEXT, expandIcon, JLabel.LEADING);
 94  
 
 95  8
         label.addMouseListener(new MouseAdapter()
 96  8
             {
 97  
                 /** {@inheritDoc} */
 98  
                 public void mouseClicked(final MouseEvent event)
 99  
                 {
 100  4
                     if (collapsed)
 101  
                     {
 102  2
                         expand();
 103  
                     }
 104  
                     else
 105  
                     {
 106  2
                         collapse();
 107  
                     }
 108  4
                 }
 109  
             });
 110  
 
 111  8
         setLayout(new BorderLayout());
 112  8
         add("North", label);
 113  8
     }
 114  
 
 115  
 
 116  
     /**
 117  
      * Expand this disclosure triangle container.
 118  
      */
 119  
     public void expand()
 120  
     {
 121  14
         setCollapsed(false);
 122  14
     }
 123  
 
 124  
     /**
 125  
      * Actually perform the expand operation.
 126  
      */
 127  
     private void doExpand()
 128  
     {
 129  14
         add("Center", container);
 130  14
         label.setIcon(collapseIcon);
 131  14
         Container rootPaneContainer = getParentRootPaneContainer();
 132  14
         if (rootPaneContainer != null)
 133  
         {
 134  8
             Dimension d0 = rootPaneContainer.getSize();
 135  8
             Dimension d1 = container.getSize();
 136  8
             Dimension d2 = container.getPreferredSize();
 137  8
             rootPaneContainer.setSize(d0.width, d0.height + Math.max(d1.height, d2.height));
 138  
         }
 139  14
     }
 140  
 
 141  
     /**
 142  
      * Collapse this disclosure triangle container.
 143  
      */
 144  
     public void collapse()
 145  
     {
 146  13
         setCollapsed(true);
 147  13
     }
 148  
 
 149  
     /**
 150  
      * Actually perform the collapse operation.
 151  
      */
 152  
     private void doCollapse()
 153  
     {
 154  13
         remove(container);
 155  13
         label.setIcon(expandIcon);
 156  13
         Container rootPaneContainer = getParentRootPaneContainer();
 157  13
         if (rootPaneContainer != null)
 158  
         {
 159  8
             Dimension d0 = rootPaneContainer.getSize();
 160  8
             Dimension d1 = container.getSize();
 161  8
             Dimension d2 = container.getPreferredSize();
 162  8
             rootPaneContainer.setSize(d0.width, d0.height - Math.max(d1.height, d2.height));
 163  
         }
 164  13
     }
 165  
 
 166  
     /**
 167  
      * Return true if this disclosure triangle container is collapsed.
 168  
      *
 169  
      * @return true if this disclosure triangle container is collapsed
 170  
      */
 171  
     public boolean isCollapsed()
 172  
     {
 173  10
         return collapsed;
 174  
     }
 175  
 
 176  
     /**
 177  
      * Set to true to collapse this disclosure triangle container.  Alternatively, call
 178  
      * <code>collapse()</code> or <code>expand()</code> as appropriate.
 179  
      *
 180  
      * <p>This is a bound property.</p>
 181  
      *
 182  
      * @param collapsed true to collapse this disclosure triangle container
 183  
      */
 184  
     public void setCollapsed(final boolean collapsed)
 185  
     {
 186  27
         boolean oldCollapsed = this.collapsed;
 187  27
         if (collapsed && !oldCollapsed)
 188  
         {
 189  13
             doCollapse();
 190  
         }
 191  27
         if (!collapsed && oldCollapsed)
 192  
         {
 193  14
             doExpand();
 194  
         }
 195  27
         this.collapsed = collapsed;
 196  27
         firePropertyChange("collapsed", oldCollapsed, this.collapsed);
 197  27
     }
 198  
 
 199  
     /**
 200  
      * Return the parent root pane container for this disclosure triangle container
 201  
      * or null if one does not exist.
 202  
      *
 203  
      * @return the parent root pane container for this disclosure triangle container
 204  
      *    or null if one does not exist
 205  
      */
 206  
     private Container getParentRootPaneContainer()
 207  
     {
 208  27
         Container c = this;
 209  91
         while (!(c instanceof RootPaneContainer))
 210  
         {
 211  75
             if (c.getParent() == null)
 212  
             {
 213  11
                 return null;
 214  
             }
 215  64
             c = c.getParent();
 216  
         }
 217  16
         return c;
 218  
     }
 219  
 
 220  
     /**
 221  
      * Return the label text for this disclosure triangle container.
 222  
      *
 223  
      * @return the label text for this disclosure triangle container
 224  
      */
 225  
     public String getLabelText()
 226  
     {
 227  3
         return label.getText();
 228  
     }
 229  
 
 230  
     /**
 231  
      * Set the label text for this disclosure triangle container to <code>labelText</code>.
 232  
      *
 233  
      * <p>This is a bound property.</p>
 234  
      *
 235  
      * @param labelText label text for this disclosure triangle container
 236  
      */
 237  
     public void setLabelText(final String labelText)
 238  
     {
 239  2
         String oldLabelText = label.getText();
 240  2
         label.setText(labelText);
 241  2
         firePropertyChange("labelText", oldLabelText, label.getText());
 242  2
     }
 243  
 
 244  
     /**
 245  
      * Return the collapse icon for this disclosure triangle container.
 246  
      *
 247  
      * @return the collapse icon for this disclosure triangle container
 248  
      */
 249  
     public Icon getCollapseIcon()
 250  
     {
 251  7
         return collapseIcon;
 252  
     }
 253  
 
 254  
     /**
 255  
      * Set the collapse icon for this disclosure triangle container to <code>collapseIcon</code>.
 256  
      *
 257  
      * <p>This is a bound property.</p>
 258  
      *
 259  
      * @param collapseIcon collapse icon for this disclosure triangle container
 260  
      */
 261  
     public void setCollapseIcon(final Icon collapseIcon)
 262  
     {
 263  6
         Icon oldCollapseIcon = this.collapseIcon;
 264  6
         this.collapseIcon = collapseIcon;
 265  6
         firePropertyChange("collapseIcon", oldCollapseIcon, this.collapseIcon);
 266  6
         if (!collapsed)
 267  
         {
 268  2
             label.setIcon(this.collapseIcon);
 269  
         }
 270  6
     }
 271  
 
 272  
     /**
 273  
      * Return the expand icon for this disclosure triangle container.
 274  
      *
 275  
      * @return the expand icon for this disclosure triangle container
 276  
      */
 277  
     public Icon getExpandIcon()
 278  
     {
 279  7
         return expandIcon;
 280  
     }
 281  
 
 282  
     /**
 283  
      * Set the expand icon for this disclosure triangle container to <code>expandIcon</code>.
 284  
      *
 285  
      * <p>This is a bound property.</p>
 286  
      *
 287  
      * @param expandIcon expand icon for this disclosure triangle container
 288  
      */
 289  
     public void setExpandIcon(final Icon expandIcon)
 290  
     {
 291  6
         Icon oldExpandIcon = this.expandIcon;
 292  6
         this.expandIcon = expandIcon;
 293  6
         firePropertyChange("expandIcon", oldExpandIcon, this.expandIcon);
 294  6
         if (collapsed)
 295  
         {
 296  4
             label.setIcon(this.expandIcon);
 297  
         }
 298  6
     }
 299  
 }