package com.onaro.sanscreen.client;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Stack;
import javax.swing.Icon;
import com.onaro.client.ClientUIUtils;
import com.onaro.client.ProblemState;
/**
* This class receives messages from external processes and save them in a stack-type-of container
* to be published to subscriber of this class later on.
*
* The policy of how these messages are advertised is as follow:
*
* - Using {@link #setMessage(String)} a new message is added into a stack-like container
* {@link IndexedRemovalStack}.
*
- The top most message saved in the stack is the one being advertised.
*
- If a message is cleared up from the stack (not necessary from the top) the top most message
* is displayed.
*
- The process that add a new message is responsible to clean it by calling {@link #cleanMessage(com.onaro.sanscreen.client.MessageManager.Message)}
*
*
*
* We use this class in {@link SanscreenStatusBar} which is a subscriber to display messages in the
* status area, please see {@link SanscreenStatusBar#createMessageStatusJPanel}
*
* @since 5/6/2008
* @author john.cohen
*
*/
public final class MessageManager {
public static final String PROP_CURRENT_MESSAGE = "currentMessage"; //$NON-NLS-1$
private Stack stack;
private PropertyChangeSupport subscribers;
public MessageManager(){
stack = new Stack();
subscribers = new PropertyChangeSupport(this);
}
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
subscribers.addPropertyChangeListener(listener);
}
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
subscribers.removePropertyChangeListener(listener);
}
public Message addErrorMessage(final String message) {
return addMessage(message, ProblemState.ERROR);
}
public Message addWarnMessage(final String message) {
return addMessage(message, ProblemState.WARNING);
}
public Message addInfoMessage(final String message) {
return addMessage(message, ProblemState.INFO);
}
public Message getLastMessage() {
if (!stack.isEmpty()) {
return stack.peek();
}
return null;
}
/**
* Adds a message to be advertised.
*
* @param message message to be advertised.
* @return Message class that is being used to later on cleared up the message from the stack.
*/
private Message addMessage(final String message, final ProblemState category) {
Message oldMessage = null;
if (!stack.isEmpty())
oldMessage = stack.peek();
final Message newMessage = new Message(message, category);
stack.push(newMessage);
synchronized(subscribers){
subscribers.firePropertyChange(PROP_CURRENT_MESSAGE, oldMessage, newMessage);
}
return newMessage;
}
/**
* Removes a message from the stack. It uses the object returned by {@link #setMessage(String)}
*
* @param Message message to be deleted.
*/
private void cleanMessage(final Message oldMessage){
stack.remove(oldMessage);
Message newMessage = null;
if (!stack.isEmpty())
newMessage = stack.peek();
synchronized(subscribers){
subscribers.firePropertyChange(PROP_CURRENT_MESSAGE, oldMessage, newMessage);
}
}
/**
* Immutable thread safe class. It represents a message to be displayed.
* Instances of this class are managed by {@link MessageManager}
*/
public class Message {
private final String message;
private final Icon icon;
public Message(final String message, final ProblemState category) {
this.message = message;
this.icon = ClientUIUtils.getProblemStateIcon(category);
}
public String getMessage() {
return message;
}
public Icon getIcon(){
return icon;
}
public void clean(){
cleanMessage(this);
}
}
}