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 /** 035 * Default width of a notification 036 */ 037 public static final int DEFAULT_CONTENT_WIDTH = 350; 038 039 // some standard duration values (in milliseconds) 040 041 /** 042 * Very short and very easy to grasp message (3 s). 043 * E.g. "Please select at least one node". 044 */ 045 public static final int TIME_SHORT = Main.pref.getInteger("notification-time-short-ms", 3000); 046 047 /** 048 * Short message of one or two lines (5 s). 049 */ 050 public static final int TIME_DEFAULT = Main.pref.getInteger("notification-time-default-ms", 5000); 051 052 /** 053 * Somewhat longer message (10 s). 054 */ 055 public static final int TIME_LONG = Main.pref.getInteger("notification-time-long-ms", 10_000); 056 057 /** 058 * Long text. 059 * (Make sure is still sensible to show as a notification) 060 */ 061 public static final int TIME_VERY_LONG = Main.pref.getInteger("notification-time-very_long-ms", 20_000); 062 063 private Component content; 064 private int duration = Notification.TIME_DEFAULT; 065 private Icon icon; 066 private String helpTopic; 067 068 /** 069 * Constructs a new {@code Notification} without content. 070 */ 071 public Notification() { 072 // nothing to do. 073 } 074 075 /** 076 * Constructs a new {@code Notification} with the given textual content. 077 * @param msg The text to display 078 */ 079 public Notification(String msg) { 080 this(); 081 setContent(msg); 082 } 083 084 /** 085 * Set the content of the message. 086 * 087 * @param content any Component to be shown 088 * 089 * @return the current Object, for convenience 090 * @see #setContent(java.lang.String) 091 */ 092 public Notification setContent(Component content) { 093 this.content = content; 094 return this; 095 } 096 097 /** 098 * Set the notification text. (Convenience method) 099 * 100 * @param msg the message String. Will be wrapped in <html>, so 101 * you can use <br> and other markup directly. 102 * 103 * @return the current Object, for convenience 104 * @see #Notification(java.lang.String) 105 */ 106 public Notification setContent(String msg) { 107 JMultilineLabel lbl = new JMultilineLabel(msg); 108 lbl.setMaxWidth(DEFAULT_CONTENT_WIDTH); 109 lbl.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); 110 lbl.setForeground(Color.BLACK); 111 content = lbl; 112 return this; 113 } 114 115 /** 116 * Set the time after which the message is hidden. 117 * 118 * @param duration the time (in milliseconds) 119 * Preset values {@link #TIME_SHORT}, {@link #TIME_DEFAULT}, {@link #TIME_LONG} 120 * and {@link #TIME_VERY_LONG} can be used. 121 * @return the current Object, for convenience 122 */ 123 public Notification setDuration(int duration) { 124 this.duration = duration; 125 return this; 126 } 127 128 /** 129 * Set an icon to display on the left part of the message window. 130 * 131 * @param icon the icon (null means no icon is displayed) 132 * @return the current Object, for convenience 133 */ 134 public Notification setIcon(Icon icon) { 135 this.icon = icon; 136 return this; 137 } 138 139 /** 140 * Set an icon to display on the left part of the message window by 141 * choosing from the default JOptionPane icons. 142 * 143 * @param messageType one of the following: JOptionPane.ERROR_MESSAGE, 144 * JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, 145 * JOptionPane.QUESTION_MESSAGE, JOptionPane.PLAIN_MESSAGE 146 * @return the current Object, for convenience 147 */ 148 public Notification setIcon(int messageType) { 149 switch (messageType) { 150 case JOptionPane.ERROR_MESSAGE: 151 return setIcon(UIManager.getIcon("OptionPane.errorIcon")); 152 case JOptionPane.INFORMATION_MESSAGE: 153 return setIcon(UIManager.getIcon("OptionPane.informationIcon")); 154 case JOptionPane.WARNING_MESSAGE: 155 return setIcon(UIManager.getIcon("OptionPane.warningIcon")); 156 case JOptionPane.QUESTION_MESSAGE: 157 return setIcon(UIManager.getIcon("OptionPane.questionIcon")); 158 case JOptionPane.PLAIN_MESSAGE: 159 return setIcon(null); 160 default: 161 throw new IllegalArgumentException("Unknown message type!"); 162 } 163 } 164 165 /** 166 * Display a help button at the bottom of the notification window. 167 * @param helpTopic the help topic 168 * @return the current Object, for convenience 169 */ 170 public Notification setHelpTopic(String helpTopic) { 171 this.helpTopic = helpTopic; 172 return this; 173 } 174 175 /** 176 * Gets the content component to use. 177 * @return The content 178 */ 179 public Component getContent() { 180 return content; 181 } 182 183 /** 184 * Gets the time the notification should be displayed 185 * @return The time to display the notification 186 */ 187 public int getDuration() { 188 return duration; 189 } 190 191 /** 192 * Gets the icon that should be displayed next to the notification 193 * @return The icon to display 194 */ 195 public Icon getIcon() { 196 return icon; 197 } 198 199 /** 200 * Gets the help topic for this notification 201 * @return The help topic 202 */ 203 public String getHelpTopic() { 204 return helpTopic; 205 } 206 207 /** 208 * Display the notification. 209 */ 210 public void show() { 211 NotificationManager.getInstance().showNotification(this); 212 } 213}