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