001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui;
003
004import java.awt.Component;
005
006import javax.swing.Icon;
007import javax.swing.JOptionPane;
008import javax.swing.UIManager;
009
010import org.openstreetmap.josm.Main;
011import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
012
013/**
014 * A Notification Message similar to a popup window, but without disrupting the
015 * user's workflow.
016 *
017 * Non-modal info panel that vanishes after a certain time.
018 *
019 * This class only holds the data for a notification, {@link NotificationManager}
020 * is responsible for building the message panel and displaying it on screen.
021 *
022 * example:
023 * <pre>
024 *      Notification note = new Notification("Hi there!");
025 *      note.setIcon(JOptionPane.INFORMATION_MESSAGE); // optional
026 *      note.setDuration(Notification.TIME_SHORT); // optional
027 *      note.show();
028 * </pre>
029 */
030public class Notification {
031
032    public final static int DEFAULT_CONTENT_WIDTH = 350;
033
034    // some standard duration values (in milliseconds)
035
036    /**
037     * Very short and very easy to grasp message (3 s).
038     * E.g. "Please select at least one node".
039     */
040    public final static int TIME_SHORT = Main.pref.getInteger("notification-time-short-ms", 3000);
041    /**
042     * Short message of one or two lines (5 s).
043     */
044    public final static int TIME_DEFAULT = Main.pref.getInteger("notification-time-default-ms", 5000);
045    /**
046     * Somewhat longer message (10 s).
047     */
048    public final static int TIME_LONG = Main.pref.getInteger("notification-time-long-ms", 10000);
049    /**
050     * Long text.
051     * (Make sure is still sensible to show as a notification)
052     */
053    public final static int TIME_VERY_LONG = Main.pref.getInteger("notification-time-very_long-ms", 20000);
054
055    private Component content;
056    private int duration;
057    private Icon icon;
058    private String helpTopic;
059
060    /**
061     * Constructs a new {@code Notification} without content.
062     */
063    public Notification() {
064        duration = NotificationManager.defaultNotificationTime;
065    }
066
067    /**
068     * Constructs a new {@code Notification} with the given textual content.
069     * @param msg The text to display
070     */
071    public Notification(String msg) {
072        this();
073        setContent(msg);
074    }
075
076    /**
077     * Set the content of the message.
078     *
079     * @param content any Component to be shown
080     *
081     * @see #setContent(java.lang.String)
082     * @return the current Object, for convenience
083     */
084    public Notification setContent(Component content) {
085        this.content = content;
086        return this;
087    }
088
089    /**
090     * Set the notification text. (Convenience method)
091     *
092     * @param msg the message String. Will be wrapped in &lt;html&gt;, so
093     * you can use &lt;br&gt; and other markup directly.
094     *
095     * @see #Notification(java.lang.String)
096     * @return the current Object, for convenience
097     */
098    public Notification setContent(String msg) {
099        JMultilineLabel lbl = new JMultilineLabel(msg);
100        lbl.setMaxWidth(DEFAULT_CONTENT_WIDTH);
101        content = lbl;
102        return this;
103    }
104
105    /**
106     * Set the time after which the message is hidden.
107     *
108     * @param duration the time (in milliseconds)
109     * Preset values {@link #TIME_SHORT}, {@link #TIME_DEFAULT}, {@link #TIME_LONG}
110     * and {@link #TIME_VERY_LONG} can be used.
111     * @return the current Object, for convenience
112     */
113    public Notification setDuration(int duration) {
114        this.duration = duration;
115        return this;
116    }
117
118    /**
119     * Set an icon to display on the left part of the message window.
120     *
121     * @param icon the icon (null means no icon is displayed)
122     * @return the current Object, for convenience
123     */
124    public Notification setIcon(Icon icon) {
125        this.icon = icon;
126        return this;
127    }
128
129    /**
130     * Set an icon to display on the left part of the message window by
131     * choosing from the default JOptionPane icons.
132     *
133     * @param messageType one of the following: JOptionPane.ERROR_MESSAGE,
134     * JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE,
135     * JOptionPane.QUESTION_MESSAGE, JOptionPane.PLAIN_MESSAGE
136     * @return the current Object, for convenience
137     */
138    public Notification setIcon(int messageType) {
139        switch (messageType) {
140            case JOptionPane.ERROR_MESSAGE:
141                return setIcon(UIManager.getIcon("OptionPane.errorIcon"));
142            case JOptionPane.INFORMATION_MESSAGE:
143                return setIcon(UIManager.getIcon("OptionPane.informationIcon"));
144            case JOptionPane.WARNING_MESSAGE:
145                return setIcon(UIManager.getIcon("OptionPane.warningIcon"));
146            case JOptionPane.QUESTION_MESSAGE:
147                return setIcon(UIManager.getIcon("OptionPane.questionIcon"));
148            case JOptionPane.PLAIN_MESSAGE:
149                return setIcon(null);
150            default:
151                throw new IllegalArgumentException("Unknown message type!");
152        }
153    }
154
155    /**
156     * Display a help button at the bottom of the notification window.
157     * @param helpTopic the help topic
158     * @return the current Object, for convenience
159     */
160    public Notification setHelpTopic(String helpTopic) {
161        this.helpTopic = helpTopic;
162        return this;
163    }
164
165    public Component getContent() {
166        return content;
167    }
168
169    public int getDuration() {
170        return duration;
171    }
172
173    public Icon getIcon() {
174        return icon;
175    }
176
177    public String getHelpTopic() {
178        return helpTopic;
179    }
180
181    /**
182     * Display the notification.
183     */
184    public void show() {
185        NotificationManager.getInstance().showNotification(this);
186    }
187}