Coverage Report - org.dishevelled.identify.IdLabel
 
Classes in this File Line Coverage Branch Coverage Complexity
IdLabel
96%
125/129
91%
57/62
2.097
IdLabel$1
11%
1/9
0%
0/4
2.097
 
 1  
 /*
 2  
 
 3  
     dsh-identify  Lightweight components for identifiable beans.
 4  
     Copyright (c) 2003-2012 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.identify;
 25  
 
 26  
 import java.awt.Image;
 27  
 import java.awt.Dimension;
 28  
 import java.awt.Rectangle;
 29  
 import java.awt.Graphics;
 30  
 import java.awt.ComponentOrientation;
 31  
 
 32  
 import java.awt.event.MouseEvent;
 33  
 import java.awt.event.MouseAdapter;
 34  
 import java.awt.event.MouseListener;
 35  
 
 36  
 import javax.swing.Icon;
 37  
 import javax.swing.JLabel;
 38  
 import javax.swing.ImageIcon;
 39  
 
 40  
 import org.dishevelled.iconbundle.IconSize;
 41  
 import org.dishevelled.iconbundle.IconState;
 42  
 import org.dishevelled.iconbundle.IconBundle;
 43  
 import org.dishevelled.iconbundle.IconTextDirection;
 44  
 
 45  
 /**
 46  
  * An extension of JLabel that displays the name property value
 47  
  * and appropriate icon from an icon bundle for a given bean.
 48  
  *
 49  
  * @author  Michael Heuer
 50  
  * @version $Revision: 1059 $ $Date: 2012-01-03 14:03:02 -0600 (Tue, 03 Jan 2012) $
 51  
  */
 52  
 public final class IdLabel
 53  
     extends JLabel
 54  
 {
 55  
     /** Default icon size. */
 56  1
     public static final IconSize DEFAULT_ICON_SIZE = IconSize.DEFAULT_32X32;
 57  
 
 58  
     /** Default icon state. */
 59  1
     public static final IconState DEFAULT_ICON_STATE = IconState.NORMAL;
 60  
 
 61  
     /** Default icon text direction. */
 62  1
     private static final IconTextDirection DEFAULT_ICON_TEXT_DIRECTION = IconTextDirection.LEFT_TO_RIGHT;
 63  
 
 64  
     /** Bound value property. */
 65  
     private Object value;
 66  
 
 67  
     /** Icon size. */
 68  205
     private IconSize iconSize = DEFAULT_ICON_SIZE;
 69  
 
 70  
     /** Icon state. */
 71  205
     private IconState iconState = DEFAULT_ICON_STATE;
 72  
 
 73  
     /** Icon text direction. */
 74  205
     private IconTextDirection iconTextDirection = DEFAULT_ICON_TEXT_DIRECTION;
 75  
 
 76  
     /** ImageIcon wrapper for image from icon bundle. */
 77  
     private transient ImageIcon imageIcon;
 78  
 
 79  
     /** Dirty flag. */
 80  205
     private transient boolean dirty = false;
 81  
 
 82  
     /** Mouseover mouse listener. */
 83  205
     private MouseListener mouseoverListener = new MouseAdapter()
 84  205
         {
 85  
             /** {@inheritDoc} */
 86  
             public void mouseEntered(final MouseEvent e)
 87  
             {
 88  0
                 if (getIconState().equals(IconState.NORMAL))
 89  
                 {
 90  0
                     setIconState(IconState.MOUSEOVER);
 91  0
                     repaint();
 92  
                 }
 93  0
             }
 94  
 
 95  
             /** {@inheritDoc} */
 96  
             public void mouseExited(final MouseEvent e)
 97  
             {
 98  0
                 if (getIconState().equals(IconState.MOUSEOVER))
 99  
                 {
 100  0
                     setIconState(IconState.NORMAL);
 101  0
                     repaint();
 102  
                 }
 103  0
             }
 104  
         };
 105  
 
 106  
     /**
 107  
      * Cache of the previous state, for use in returning to the
 108  
      * proper state following a call of <code>setEnabled(true)</code>.
 109  
      */
 110  205
     private transient IconState previousState = DEFAULT_ICON_STATE;
 111  
 
 112  
 
 113  
     /**
 114  
      * Create a new label with a null value.
 115  
      */
 116  
     public IdLabel()
 117  
     {
 118  34
         super();
 119  
 
 120  34
         addMouseListener(mouseoverListener);
 121  
 
 122  34
         setValue(null);
 123  34
         rebuild();
 124  34
     }
 125  
 
 126  
     /**
 127  
      * Create a new label for the specified value.
 128  
      *
 129  
      * @param value value
 130  
      */
 131  
     public IdLabel(final Object value)
 132  
     {
 133  93
         super();
 134  
 
 135  93
         addMouseListener(mouseoverListener);
 136  
 
 137  93
         setValue(value);
 138  93
         rebuild();
 139  93
     }
 140  
 
 141  
     /**
 142  
      * Create a new label for the specified value with the specified icon size.
 143  
      *
 144  
      * @param value value
 145  
      * @param iconSize icon size, must not be null
 146  
      */
 147  
     public IdLabel(final Object value, final IconSize iconSize)
 148  
     {
 149  78
         super();
 150  
 
 151  78
         addMouseListener(mouseoverListener);
 152  
 
 153  78
         setValue(value);
 154  78
         setIconSize(iconSize);
 155  77
         rebuild();
 156  77
     }
 157  
 
 158  
 
 159  
     /**
 160  
      * Return the value for this label.
 161  
      *
 162  
      * @return the value for this label
 163  
      */
 164  
     public Object getValue()
 165  
     {
 166  9
         return value;
 167  
     }
 168  
 
 169  
     /**
 170  
      * Set the value for this label to <code>value</code>.
 171  
      *
 172  
      * <p>This is a bound property.</p>
 173  
      *
 174  
      * @param value value for this label
 175  
      */
 176  
     public void setValue(final Object value)
 177  
     {
 178  225
         Object oldValue = this.value;
 179  225
         this.value = value;
 180  225
         firePropertyChange("value", oldValue, this.value);
 181  
 
 182  225
         setDirty(true);
 183  225
     }
 184  
 
 185  
     /**
 186  
      * Return the icon size for this label.
 187  
      *
 188  
      * @return the icon size for this label
 189  
      */
 190  
     public IconSize getIconSize()
 191  
     {
 192  166
         return iconSize;
 193  
     }
 194  
 
 195  
     /**
 196  
      * Set the icon size for this label to <code>iconSize</code>.
 197  
      *
 198  
      * <p>This is a bound property.</p>
 199  
      *
 200  
      * @param iconSize icon size, must not be null
 201  
      */
 202  
     public void setIconSize(final IconSize iconSize)
 203  
     {
 204  243
         if (iconSize == null)
 205  
         {
 206  2
             throw new IllegalArgumentException("iconSize must not be null");
 207  
         }
 208  
 
 209  241
         IconSize oldIconSize = this.iconSize;
 210  241
         this.iconSize = iconSize;
 211  
 
 212  241
         if (!oldIconSize.equals(this.iconSize))
 213  
         {
 214  165
             setDirty(true);
 215  165
             firePropertyChange("iconSize", oldIconSize, iconSize);
 216  
         }
 217  241
     }
 218  
 
 219  
     /**
 220  
      * Return the icon state for this label.
 221  
      *
 222  
      * @return the icon state for this label
 223  
      */
 224  
     public IconState getIconState()
 225  
     {
 226  55
         return iconState;
 227  
     }
 228  
 
 229  
     /**
 230  
      * Set the icon state for this label to <code>iconState</code>.
 231  
      *
 232  
      * <p>This is a bound property.</p>
 233  
      *
 234  
      * @param iconState icon state, must not be null
 235  
      */
 236  
     public void setIconState(final IconState iconState)
 237  
     {
 238  38
         if (iconState == null)
 239  
         {
 240  1
             throw new IllegalArgumentException("iconState must not be null");
 241  
         }
 242  
 
 243  37
         IconState oldIconState = this.iconState;
 244  37
         this.iconState = iconState;
 245  
 
 246  37
         if (!oldIconState.equals(this.iconState))
 247  
         {
 248  31
             setDirty(true);
 249  31
             firePropertyChange("iconState", oldIconState, this.iconState);
 250  
         }
 251  37
     }
 252  
 
 253  
     /**
 254  
      * Return the icon text direction for this label.
 255  
      *
 256  
      * @return the icon text direction for this label
 257  
      */
 258  
     IconTextDirection getIconTextDirection()
 259  
     {
 260  5
         return iconTextDirection;
 261  
     }
 262  
 
 263  
     /** {@inheritDoc} */
 264  
     public void setComponentOrientation(final ComponentOrientation orientation)
 265  
     {
 266  5
         ComponentOrientation oldOrientation = getComponentOrientation();
 267  
 
 268  5
         if (!oldOrientation.equals(orientation))
 269  
         {
 270  5
             if (orientation != null)
 271  
             {
 272  4
                 iconTextDirection = orientation.isLeftToRight()
 273  
                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
 274  
 
 275  4
                 setDirty(true);
 276  
             }
 277  
         }
 278  
 
 279  5
         super.setComponentOrientation(orientation);
 280  5
     }
 281  
 
 282  
     /** {@inheritDoc} */
 283  
     public void applyComponentOrientation(final ComponentOrientation orientation)
 284  
     {
 285  3
         ComponentOrientation oldOrientation = getComponentOrientation();
 286  
 
 287  3
         if (!oldOrientation.equals(orientation))
 288  
         {
 289  3
             if (orientation != null)
 290  
             {
 291  2
                 iconTextDirection = orientation.isLeftToRight()
 292  
                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
 293  
 
 294  2
                 setDirty(true);
 295  
             }
 296  
         }
 297  
 
 298  3
         super.applyComponentOrientation(orientation);
 299  2
     }
 300  
 
 301  
     /** {@inheritDoc} */
 302  
     public void setEnabled(final boolean enabled)
 303  
     {
 304  14
         boolean previousEnabled = isEnabled();
 305  
 
 306  14
         if (enabled && !previousEnabled)
 307  
         {
 308  6
             setIconState(previousState);
 309  
         }
 310  8
         else if (!enabled && previousEnabled)
 311  
         {
 312  6
             previousState = getIconState();
 313  6
             setIconState(IconState.DISABLED);
 314  
         }
 315  
 
 316  14
         super.setEnabled(enabled);
 317  
 
 318  14
         setDirty(true);
 319  14
     }
 320  
 
 321  
     /**
 322  
      * Set the dirty flag to the logical OR of <code>dirty</code>
 323  
      * and the previous dirty state.
 324  
      *
 325  
      * @param dirty dirty flag
 326  
      */
 327  
     private void setDirty(final boolean dirty)
 328  
     {
 329  441
         this.dirty = (this.dirty || dirty);
 330  441
     }
 331  
 
 332  
     /**
 333  
      * Return true if a rebuild of the text and icon properties
 334  
      * is necessary.
 335  
      *
 336  
      * @return true if a rebuild of the text and icon properties
 337  
      *    is necessary
 338  
      */
 339  
     private boolean isDirty()
 340  
     {
 341  1095
         return dirty;
 342  
     }
 343  
 
 344  
     /**
 345  
      * Rebuild the text and icon properties of this label
 346  
      * with the name property and icon bundle image of
 347  
      * <code>getValue()</code>, respectively.
 348  
      */
 349  
     private void rebuild()
 350  
     {
 351  590
         String name = IdentifyUtils.getNameFor(value);
 352  590
         setText(name);
 353  
 
 354  590
         IconBundle iconBundle = IdentifyUtils.getIconBundleFor(value);
 355  
 
 356  590
         if (iconBundle == null)
 357  
         {
 358  216
             super.setIcon(null);
 359  216
             imageIcon = null;
 360  
         }
 361  
         else
 362  
         {
 363  374
             Image image = iconBundle.getImage(this, iconTextDirection, iconState, iconSize);
 364  
 
 365  374
             if (imageIcon == null)
 366  
             {
 367  129
                 imageIcon = new ImageIcon(image);
 368  
             }
 369  
             else
 370  
             {
 371  245
                 imageIcon.setImage(image);
 372  
             }
 373  
 
 374  374
             super.setIcon(imageIcon);
 375  
         }
 376  
 
 377  590
         dirty = false;
 378  590
     }
 379  
 
 380  
     /** {@inheritDoc} */
 381  
     public String getText()
 382  
     {
 383  535
         if (isDirty())
 384  
         {
 385  216
             rebuild();
 386  
         }
 387  535
         return super.getText();
 388  
     }
 389  
 
 390  
     /** {@inheritDoc} */
 391  
     public Icon getIcon()
 392  
     {
 393  118
         if (isDirty())
 394  
         {
 395  4
             rebuild();
 396  
         }
 397  118
         return imageIcon;
 398  
     }
 399  
 
 400  
     /** {@inheritDoc} */
 401  
     public Icon getDisabledIcon()
 402  
     {
 403  10
         if (isDirty())
 404  
         {
 405  4
             rebuild();
 406  
         }
 407  10
         return imageIcon;
 408  
     }
 409  
 
 410  
     /** {@inheritDoc} */
 411  
     public Rectangle getBounds()
 412  
     {
 413  72
         if (isDirty())
 414  
         {
 415  18
             rebuild();
 416  
         }
 417  72
         return super.getBounds();
 418  
     }
 419  
 
 420  
     /** {@inheritDoc} */
 421  
     public Rectangle getBounds(final Rectangle rv)
 422  
     {
 423  36
         if (isDirty())
 424  
         {
 425  18
             rebuild();
 426  
         }
 427  36
         return super.getBounds(rv);
 428  
     }
 429  
 
 430  
     /** {@inheritDoc} */
 431  
     public Dimension getMaximumSize()
 432  
     {
 433  36
         if (isDirty())
 434  
         {
 435  18
             rebuild();
 436  
         }
 437  36
         return super.getMaximumSize();
 438  
     }
 439  
 
 440  
     /** {@inheritDoc} */
 441  
     public Dimension getMinimumSize()
 442  
     {
 443  36
         if (isDirty())
 444  
         {
 445  18
             rebuild();
 446  
         }
 447  36
         return super.getMinimumSize();
 448  
     }
 449  
 
 450  
     /** {@inheritDoc} */
 451  
     public Dimension getPreferredSize()
 452  
     {
 453  36
         if (isDirty())
 454  
         {
 455  18
             rebuild();
 456  
         }
 457  36
         return super.getPreferredSize();
 458  
     }
 459  
 
 460  
     /** {@inheritDoc} */
 461  
     public Dimension getSize()
 462  
     {
 463  36
         if (isDirty())
 464  
         {
 465  18
             rebuild();
 466  
         }
 467  36
         return super.getSize();
 468  
     }
 469  
 
 470  
     /** {@inheritDoc} */
 471  
     public Rectangle getVisibleRect()
 472  
     {
 473  36
         if (isDirty())
 474  
         {
 475  18
             rebuild();
 476  
         }
 477  36
         return super.getVisibleRect();
 478  
     }
 479  
 
 480  
     /** {@inheritDoc} */
 481  
     public int getHeight()
 482  
     {
 483  72
         if (isDirty())
 484  
         {
 485  18
             rebuild();
 486  
         }
 487  72
         return super.getHeight();
 488  
     }
 489  
 
 490  
     /** {@inheritDoc} */
 491  
     public int getWidth()
 492  
     {
 493  72
         if (isDirty())
 494  
         {
 495  18
             rebuild();
 496  
         }
 497  72
         return super.getWidth();
 498  
     }
 499  
 
 500  
     /** {@inheritDoc} */
 501  
     public void paintComponent(final Graphics g)
 502  
     {
 503  0
         if (isDirty())
 504  
         {
 505  0
             rebuild();
 506  
         }
 507  0
         super.paintComponent(g);
 508  0
     }
 509  
 }