001    package org.springframework.richclient.components;
002    
003    import org.springframework.richclient.core.Message;
004    import org.springframework.richclient.core.Severity;
005    import org.springframework.richclient.image.IconSource;
006    import org.springframework.richclient.application.ApplicationServicesLocator;
007    
008    import javax.swing.*;
009    import java.util.List;
010    import java.util.ArrayList;
011    import java.util.HashMap;
012    import java.util.Stack;
013    import java.awt.*;
014    
015    public class MessagableTabbedPane extends JTabbedPane implements MessagableTab
016    {
017    
018        private List<TabMessages> messages = new ArrayList<TabMessages>();
019    
020        private IconSource iconSource;
021    
022        private Icon oldIcon;
023    
024        private String oldToolTipText;
025    
026        public MessagableTabbedPane()
027        {
028            super();
029        }
030    
031        public MessagableTabbedPane(int tabPlacement)
032        {
033            super(tabPlacement);
034        }
035    
036        public MessagableTabbedPane(int tabPlacement, int tabPolicy)
037        {
038            super(tabPlacement, tabPolicy);
039        }
040    
041        private static class TabMessages
042        {
043            private int numberOfErrors = 0;
044            private HashMap<Object, Message> messages = new HashMap<Object, Message>();
045            private Stack<Message> messageStack = new Stack<Message>();
046    
047            public boolean put(Object key, Message message)
048            {
049                boolean firstErrorOrLessErrors = false;
050                Message oldMessage = (Message)this.messages.get(key);
051                if (oldMessage != message)
052                {
053                    if ((oldMessage == null) || (message == null) || (oldMessage.getSeverity() != message.getSeverity()))
054                    {
055                        if ((message != null) && (message.getSeverity() == Severity.ERROR))
056                        {
057                            if (numberOfErrors == 0)
058                                firstErrorOrLessErrors = true;
059                            ++this.numberOfErrors;
060                            messageStack.add(message);
061                        }
062                        else if ((oldMessage != null) && (oldMessage.getSeverity() == Severity.ERROR))
063                        {
064                            --this.numberOfErrors;
065                            messageStack.remove(oldMessage);
066                            firstErrorOrLessErrors = true;
067                        }
068                    }
069                    if (message != null)
070                        this.messages.put(key, message);
071                    else
072                        this.messages.remove(key);
073                }
074                return firstErrorOrLessErrors;
075            }
076    
077            public Message get(Object key)
078            {
079                return (Message)this.messages.get(key);
080            }
081    
082            public int getNumberOfErrors()
083            {
084                return this.numberOfErrors;
085            }
086    
087            public boolean hasErrors()
088            {
089                return this.numberOfErrors > 0;
090            }
091    
092            public String getFirstMessage()
093            {
094                if (messageStack.size() > 0)
095                    return ((Message)messageStack.firstElement()).getMessage();
096    
097                return null;
098            }
099        }
100    
101        public void insertTab(String title, Icon icon, Component component, String tip, int index)
102        {
103            super.insertTab(title, icon, component, tip, index);
104            messages.add(index, new TabMessages());
105        }
106    
107        private Icon getIcon(String severityLabel)
108        {
109            if (iconSource == null)
110                iconSource = (IconSource) ApplicationServicesLocator.services().getService(IconSource.class);
111            return iconSource.getIcon("severity." + severityLabel + ".overlay");
112        }
113    
114        public void setMessage(Object source, Message message, int tabIndex)
115        {
116            TabMessages tabMessages = (TabMessages)this.messages.get(tabIndex);
117            // if first error or less errors than before, update icon/tooltip
118            if (tabMessages.put(source, message))
119            {
120                if (tabMessages.hasErrors())
121                {
122                    if (oldIcon == null) oldIcon = getIconAt(tabIndex);
123                    if (oldToolTipText == null) oldToolTipText = getToolTipTextAt(tabIndex);
124                    if (oldIcon == getIcon(Severity.ERROR.getLabel())) {
125                            oldIcon = null;
126                            oldToolTipText = null;
127                    }
128                    setIconAt(tabIndex, getIcon(Severity.ERROR.getLabel()));
129                    setToolTipTextAt(tabIndex, tabMessages.getFirstMessage());
130                }
131                else
132                {
133                    setIconAt(tabIndex, oldIcon);
134                    setToolTipTextAt(tabIndex, oldToolTipText);
135                    oldIcon = null;
136                    oldToolTipText = null;
137                }
138            }
139        }
140    }