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 }