Coverage Report - org.openpermis.editor.policy.gui.ErrorStatusUpdater
 
Classes in this File Line Coverage Branch Coverage Complexity
ErrorStatusUpdater
0%
0/40
0%
0/20
2.333
ErrorStatusUpdater$1
0%
0/5
0%
0/2
2.333
 
 1  
 /*
 2  
  * Copyright (c) 2009, Swiss Federal Department of Defence Civil Protection and Sport
 3  
  *                     (http://www.vbs.admin.ch)
 4  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 5  
  * All rights reserved.
 6  
  *
 7  
  * Licensed under the Open Permis License which accompanies this distribution,
 8  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 9  
  */
 10  
 package org.openpermis.editor.policy.gui;
 11  
 
 12  
 import static java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager;
 13  
 import static org.openpermis.editor.policy.gui.binding.ErrorBindingListener.getErrorMessage;
 14  
 import static org.openpermis.editor.policy.gui.binding.ErrorBindingListener.hasError;
 15  
 
 16  
 import java.awt.Component;
 17  
 import java.awt.Window;
 18  
 import java.beans.PropertyChangeEvent;
 19  
 import java.beans.PropertyChangeListener;
 20  
 
 21  
 import javax.swing.Icon;
 22  
 import javax.swing.JComponent;
 23  
 import javax.swing.JLabel;
 24  
 import javax.swing.SwingUtilities;
 25  
 
 26  
 import org.jdesktop.application.ResourceMap;
 27  
 
 28  
 
 29  
 /**
 30  
  * 
 31  
  * @since 0.1.0
 32  
  */
 33  0
 public class ErrorStatusUpdater
 34  
         implements PropertyChangeListener
 35  
 {
 36  
         
 37  
         //---- Static
 38  
         
 39  
         /**
 40  
          * Property for the focused window changes.
 41  
          * @since 0.1.0
 42  
          */
 43  
         private static final String FOCUSED_WINDOW = "focusedWindow";
 44  
 
 45  
         /**
 46  
          * Property for the focus owner changes.
 47  
          * @since 0.1.0
 48  
          */
 49  
         private static final String FOCUS_OWNER = "focusOwner";
 50  
         
 51  
         /**
 52  
          * Status label client property used to indicate if an error is showing.
 53  
          * @since 0.1.0
 54  
          */
 55  
         private static final String ERROR_MESSAGE = "errorStatusMessage";
 56  
 
 57  
         //---- State
 58  
         
 59  
         /**
 60  
          * The window watched.
 61  
          * @since 0.1.0
 62  
          */
 63  
         private final Window window;
 64  
         
 65  
         /**
 66  
          * The status label to modify.
 67  
          * @since 0.1.0
 68  
          */
 69  
         private final JLabel statusLabel;
 70  
         
 71  
         /**
 72  
          * The error icon to use.
 73  
          * @since 0.1.0
 74  
          */
 75  
         private final Icon errorIcon;
 76  
         
 77  
         /**
 78  
          * The normal icon if no error is set.
 79  
          * @since 0.1.0
 80  
          */
 81  
         private final Icon normalIcon;
 82  
         
 83  
         /**
 84  
          * Indicates if listening for focus changes.
 85  
          * @since 0.1.0
 86  
          */
 87  
         private boolean active;
 88  
         
 89  
         //---- Constructors
 90  
         
 91  
         /**
 92  
          * Creates and registers this error status updater.
 93  
          * @param resourceMap the resource map to use for configuration.
 94  
          * @param window the window to watch.
 95  
          * @param statusLabel the status label to use.
 96  
          * @since 0.1.0
 97  
          */
 98  0
         public ErrorStatusUpdater (ResourceMap resourceMap, Window window, JLabel statusLabel) {
 99  0
                 this.window = window;
 100  0
                 this.statusLabel = statusLabel;
 101  0
                 this.normalIcon = statusLabel.getIcon();
 102  0
                 this.errorIcon = resourceMap.getIcon("statusErrorIcon");
 103  0
                 getCurrentKeyboardFocusManager().addPropertyChangeListener(this);
 104  0
         }
 105  
         
 106  
         //---- Methods
 107  
 
 108  
         /**
 109  
          * Check if the label shows an error.
 110  
          * @param label the label to check.
 111  
          * @return {@code true} if it displays an error message.
 112  
          * @since 0.1.0
 113  
          */
 114  
         private boolean showingError (JLabel label) {
 115  0
                 final String errorMessage = (String) label.getClientProperty(ERROR_MESSAGE);
 116  0
                 if (errorMessage != null) {
 117  0
                         return errorMessage.equals(label.getText());
 118  
                 }
 119  0
                 return false;
 120  
         }
 121  
         
 122  
         /**
 123  
          * Displays an error message on the given label.
 124  
          * @param label the label to use.
 125  
          * @param errorMessage the message to display.
 126  
          * @since 0.1.0
 127  
          */
 128  
         private void showError (JLabel label, String errorMessage) {
 129  0
                 label.putClientProperty(ERROR_MESSAGE, errorMessage);
 130  0
                 label.setText(errorMessage);
 131  0
                 label.setIcon(this.errorIcon);
 132  0
         }
 133  
         
 134  
         /**
 135  
          * Clears the error message showing on the given label.
 136  
          * @param label the label to modify.
 137  
          * @since 0.1.0
 138  
          */
 139  
         private void clearError (JLabel label) {
 140  0
                 this.statusLabel.setText("");
 141  0
                 label.putClientProperty(ERROR_MESSAGE, null);
 142  0
                 label.setIcon(this.normalIcon);
 143  0
         }
 144  
         
 145  
         /**
 146  
          * Updates the status label according to the error state of the specified component.
 147  
          * @param component the component to inspect.
 148  
          * @since 0.1.0
 149  
          */
 150  
         private void update (Component component) {
 151  0
                 if (component instanceof JComponent) {
 152  0
                         final JComponent swingComponent = (JComponent) component;
 153  0
                         if (hasError(swingComponent)) {
 154  0
                                 showError(this.statusLabel, getErrorMessage(swingComponent));
 155  0
                                 return;
 156  
                         }
 157  
                 }
 158  0
                 if (showingError(this.statusLabel)) {
 159  0
                         clearError(this.statusLabel);
 160  
                 }
 161  0
         }
 162  
         
 163  
         /**
 164  
          * Deregisters this error status updater.
 165  
          * @since 0.1.0
 166  
          */
 167  
         public void dispose () {
 168  0
                 getCurrentKeyboardFocusManager().removePropertyChangeListener(this);
 169  0
         }
 170  
         
 171  
         /**
 172  
          * Shows an error message.
 173  
          * @param message the message to show.
 174  
          * @since 0.1.0
 175  
          */
 176  
         public void showError (final String message) {
 177  0
                 SwingUtilities.invokeLater(
 178  
                         new Runnable() {
 179  0
                                 public void run () {
 180  0
                                         if (message == null) {
 181  0
                                                 clearError(ErrorStatusUpdater.this.statusLabel);
 182  
                                         } else {
 183  0
                                                 showError(ErrorStatusUpdater.this.statusLabel, message);
 184  
                                         }
 185  0
                                 }
 186  
                         }
 187  
                 );
 188  0
         }
 189  
         
 190  
         //---- PropertyChangeListener
 191  
         
 192  
         /**
 193  
          * @since 0.1.0
 194  
          */
 195  
         public void propertyChange (PropertyChangeEvent event) {
 196  0
                 if (FOCUSED_WINDOW.equals(event.getPropertyName())) {
 197  0
                         this.active = event.getNewValue() == this.window;
 198  0
                         if (this.active) {
 199  0
                                 update(this.window.getFocusOwner());
 200  
                         }
 201  0
                 } else if (this.active && FOCUS_OWNER.equals(event.getPropertyName())) {
 202  0
                         if (event.getNewValue() instanceof Component) {
 203  0
                                 update((Component) event.getNewValue());
 204  
                         }
 205  
                 }
 206  0
         }
 207  
         
 208  
 }