diff --git a/src/org/openstreetmap/josm/gui/Notification.java b/src/org/openstreetmap/josm/gui/Notification.java
index 19e15d9..70bb0b8 100644
|
a
|
b
|
import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
|
| 31 | 31 | */ |
| 32 | 32 | public class Notification { |
| 33 | 33 | |
| | 34 | /** |
| | 35 | * Default width of a notification |
| | 36 | */ |
| 34 | 37 | public static final int DEFAULT_CONTENT_WIDTH = 350; |
| 35 | 38 | |
| 36 | 39 | // some standard duration values (in milliseconds) |
| … |
… |
public class Notification {
|
| 58 | 61 | public static final int TIME_VERY_LONG = Main.pref.getInteger("notification-time-very_long-ms", 20000); |
| 59 | 62 | |
| 60 | 63 | private Component content; |
| 61 | | private int duration; |
| | 64 | private int duration = Notification.TIME_DEFAULT; |
| 62 | 65 | private Icon icon; |
| 63 | 66 | private String helpTopic; |
| 64 | 67 | |
| … |
… |
public class Notification {
|
| 66 | 69 | * Constructs a new {@code Notification} without content. |
| 67 | 70 | */ |
| 68 | 71 | public Notification() { |
| 69 | | duration = NotificationManager.defaultNotificationTime; |
| | 72 | // nothing to do. |
| 70 | 73 | } |
| 71 | 74 | |
| 72 | 75 | /** |
| … |
… |
public class Notification {
|
| 169 | 172 | return this; |
| 170 | 173 | } |
| 171 | 174 | |
| | 175 | /** |
| | 176 | * Gets the content component to use. |
| | 177 | * @return The content |
| | 178 | */ |
| 172 | 179 | public Component getContent() { |
| 173 | 180 | return content; |
| 174 | 181 | } |
| 175 | 182 | |
| | 183 | /** |
| | 184 | * Gets the time the notification should be displayed |
| | 185 | * @return The time to display the notification |
| | 186 | */ |
| 176 | 187 | public int getDuration() { |
| 177 | 188 | return duration; |
| 178 | 189 | } |
| 179 | 190 | |
| | 191 | /** |
| | 192 | * Gets the icon that should be displayed next to the notification |
| | 193 | * @return The icon to display |
| | 194 | */ |
| 180 | 195 | public Icon getIcon() { |
| 181 | 196 | return icon; |
| 182 | 197 | } |
| 183 | 198 | |
| | 199 | /** |
| | 200 | * Gets the help topic for this notification |
| | 201 | * @return The help topic |
| | 202 | */ |
| 184 | 203 | public String getHelpTopic() { |
| 185 | 204 | return helpTopic; |
| 186 | 205 | } |
diff --git a/src/org/openstreetmap/josm/gui/NotificationManager.java b/src/org/openstreetmap/josm/gui/NotificationManager.java
index 49291a2..142de4f 100644
|
a
|
b
|
import javax.swing.SwingUtilities;
|
| 36 | 36 | import javax.swing.Timer; |
| 37 | 37 | |
| 38 | 38 | import org.openstreetmap.josm.Main; |
| | 39 | import org.openstreetmap.josm.data.preferences.IntegerProperty; |
| 39 | 40 | import org.openstreetmap.josm.gui.help.HelpBrowser; |
| 40 | 41 | import org.openstreetmap.josm.gui.help.HelpUtil; |
| 41 | 42 | import org.openstreetmap.josm.tools.ImageProvider; |
| … |
… |
class NotificationManager {
|
| 63 | 64 | private NotificationPanel currentNotificationPanel; |
| 64 | 65 | private final Queue<Notification> queue; |
| 65 | 66 | |
| 66 | | private static int pauseTime = Main.pref.getInteger("notification-default-pause-time-ms", 300); // milliseconds |
| 67 | | static int defaultNotificationTime = Main.pref.getInteger("notification-default-time-ms", 5000); // milliseconds |
| | 67 | private static IntegerProperty pauseTime = new IntegerProperty("notification-default-pause-time-ms", 300); // milliseconds |
| 68 | 68 | |
| 69 | 69 | private long displayTimeStart; |
| 70 | 70 | private long elapsedTime; |
| 71 | 71 | |
| 72 | | private static NotificationManager INSTANCE; |
| | 72 | private static NotificationManager instance; |
| 73 | 73 | |
| 74 | 74 | private static final Color PANEL_SEMITRANSPARENT = new Color(224, 236, 249, 230); |
| 75 | 75 | private static final Color PANEL_OPAQUE = new Color(224, 236, 249); |
| 76 | 76 | |
| 77 | | public static synchronized NotificationManager getInstance() { |
| 78 | | if (INSTANCE == null) { |
| 79 | | INSTANCE = new NotificationManager(); |
| 80 | | } |
| 81 | | return INSTANCE; |
| 82 | | } |
| 83 | | |
| 84 | 77 | NotificationManager() { |
| 85 | 78 | queue = new LinkedList<>(); |
| 86 | | hideTimer = new Timer(defaultNotificationTime, new HideEvent()); |
| | 79 | hideTimer = new Timer(Notification.TIME_DEFAULT, e -> this.stopHideTimer()); |
| 87 | 80 | hideTimer.setRepeats(false); |
| 88 | | pauseTimer = new Timer(pauseTime, new PauseFinishedEvent()); |
| | 81 | pauseTimer = new Timer(pauseTime.get(), new PauseFinishedEvent()); |
| 89 | 82 | pauseTimer.setRepeats(false); |
| 90 | 83 | unfreezeDelayTimer = new Timer(10, new UnfreezeEvent()); |
| 91 | 84 | unfreezeDelayTimer.setRepeats(false); |
| 92 | 85 | } |
| 93 | 86 | |
| | 87 | /** |
| | 88 | * Show the given notification |
| | 89 | * @param note The note to show. |
| | 90 | * @see Notification#show() |
| | 91 | */ |
| 94 | 92 | public void showNotification(Notification note) { |
| 95 | 93 | synchronized (queue) { |
| 96 | 94 | queue.add(note); |
| … |
… |
class NotificationManager {
|
| 104 | 102 | currentNotification = queue.poll(); |
| 105 | 103 | if (currentNotification == null) return; |
| 106 | 104 | |
| 107 | | currentNotificationPanel = new NotificationPanel(currentNotification); |
| | 105 | currentNotificationPanel = new NotificationPanel(currentNotification, new FreezeMouseListener(), e -> this.stopHideTimer()); |
| 108 | 106 | currentNotificationPanel.validate(); |
| 109 | 107 | |
| 110 | 108 | int margin = 5; |
| … |
… |
class NotificationManager {
|
| 146 | 144 | hideTimer.restart(); |
| 147 | 145 | } |
| 148 | 146 | |
| 149 | | private class HideEvent implements ActionListener { |
| 150 | | |
| 151 | | @Override |
| 152 | | public void actionPerformed(ActionEvent e) { |
| 153 | | hideTimer.stop(); |
| 154 | | if (currentNotificationPanel != null) { |
| 155 | | currentNotificationPanel.setVisible(false); |
| 156 | | JFrame parent = (JFrame) Main.parent; |
| 157 | | if (parent != null) { |
| 158 | | parent.getLayeredPane().remove(currentNotificationPanel); |
| 159 | | } |
| 160 | | currentNotificationPanel = null; |
| | 147 | private void stopHideTimer() { |
| | 148 | hideTimer.stop(); |
| | 149 | if (currentNotificationPanel != null) { |
| | 150 | currentNotificationPanel.setVisible(false); |
| | 151 | JFrame parent = (JFrame) Main.parent; |
| | 152 | if (parent != null) { |
| | 153 | parent.getLayeredPane().remove(currentNotificationPanel); |
| 161 | 154 | } |
| 162 | | pauseTimer.restart(); |
| | 155 | currentNotificationPanel = null; |
| 163 | 156 | } |
| | 157 | pauseTimer.restart(); |
| 164 | 158 | } |
| 165 | 159 | |
| 166 | 160 | private class PauseFinishedEvent implements ActionListener { |
| … |
… |
class NotificationManager {
|
| 186 | 180 | } |
| 187 | 181 | } |
| 188 | 182 | |
| 189 | | private class NotificationPanel extends JPanel { |
| | 183 | private static class NotificationPanel extends JPanel { |
| 190 | 184 | |
| 191 | 185 | private JPanel innerPanel; |
| 192 | 186 | |
| 193 | | NotificationPanel(Notification note) { |
| | 187 | NotificationPanel(Notification note, MouseListener freeze, ActionListener hideListener) { |
| 194 | 188 | setVisible(false); |
| 195 | | build(note); |
| | 189 | build(note, freeze, hideListener); |
| 196 | 190 | } |
| 197 | 191 | |
| 198 | 192 | public void setNotificationBackground(Color c) { |
| 199 | 193 | innerPanel.setBackground(c); |
| 200 | 194 | } |
| 201 | 195 | |
| 202 | | private void build(final Notification note) { |
| 203 | | JButton btnClose = new JButton(new HideAction()); |
| | 196 | private void build(final Notification note, MouseListener freeze, ActionListener hideListener) { |
| | 197 | JButton btnClose = new JButton(); |
| | 198 | btnClose.addActionListener(hideListener); |
| | 199 | btnClose.setIcon(ImageProvider.get("misc", "grey_x")); |
| 204 | 200 | btnClose.setPreferredSize(new Dimension(50, 50)); |
| 205 | 201 | btnClose.setMargin(new Insets(0, 0, 1, 1)); |
| 206 | 202 | btnClose.setContentAreaFilled(false); |
| … |
… |
class NotificationManager {
|
| 294 | 290 | * of a second, background color is switched twice), so there is |
| 295 | 291 | * a tiny delay before the timer really resumes. |
| 296 | 292 | */ |
| 297 | | MouseListener freeze = new FreezeMouseListener(); |
| 298 | 293 | addMouseListenerToAllChildComponents(this, freeze); |
| 299 | 294 | } |
| 300 | 295 | |
| 301 | | private void addMouseListenerToAllChildComponents(Component comp, MouseListener listener) { |
| | 296 | private static void addMouseListenerToAllChildComponents(Component comp, MouseListener listener) { |
| 302 | 297 | comp.addMouseListener(listener); |
| 303 | 298 | if (comp instanceof Container) { |
| 304 | 299 | for (Component c: ((Container) comp).getComponents()) { |
| … |
… |
class NotificationManager {
|
| 306 | 301 | } |
| 307 | 302 | } |
| 308 | 303 | } |
| | 304 | } |
| 309 | 305 | |
| 310 | | class HideAction extends AbstractAction { |
| 311 | | |
| 312 | | HideAction() { |
| 313 | | putValue(SMALL_ICON, ImageProvider.get("misc", "grey_x")); |
| 314 | | } |
| 315 | | |
| 316 | | @Override |
| 317 | | public void actionPerformed(ActionEvent e) { |
| 318 | | new HideEvent().actionPerformed(null); |
| | 306 | class FreezeMouseListener extends MouseAdapter { |
| | 307 | @Override |
| | 308 | public void mouseEntered(MouseEvent e) { |
| | 309 | if (unfreezeDelayTimer.isRunning()) { |
| | 310 | unfreezeDelayTimer.stop(); |
| | 311 | } else { |
| | 312 | hideTimer.stop(); |
| | 313 | elapsedTime += System.currentTimeMillis() - displayTimeStart; |
| | 314 | currentNotificationPanel.setNotificationBackground(PANEL_OPAQUE); |
| | 315 | currentNotificationPanel.repaint(); |
| 319 | 316 | } |
| 320 | 317 | } |
| 321 | 318 | |
| 322 | | class FreezeMouseListener extends MouseAdapter { |
| 323 | | @Override |
| 324 | | public void mouseEntered(MouseEvent e) { |
| 325 | | if (unfreezeDelayTimer.isRunning()) { |
| 326 | | unfreezeDelayTimer.stop(); |
| 327 | | } else { |
| 328 | | hideTimer.stop(); |
| 329 | | elapsedTime += System.currentTimeMillis() - displayTimeStart; |
| 330 | | currentNotificationPanel.setNotificationBackground(PANEL_OPAQUE); |
| 331 | | currentNotificationPanel.repaint(); |
| 332 | | } |
| 333 | | } |
| 334 | | |
| 335 | | @Override |
| 336 | | public void mouseExited(MouseEvent e) { |
| 337 | | unfreezeDelayTimer.restart(); |
| 338 | | } |
| | 319 | @Override |
| | 320 | public void mouseExited(MouseEvent e) { |
| | 321 | unfreezeDelayTimer.restart(); |
| 339 | 322 | } |
| 340 | 323 | } |
| 341 | 324 | |
| … |
… |
class NotificationManager {
|
| 370 | 353 | super.paintComponent(graphics); |
| 371 | 354 | } |
| 372 | 355 | } |
| | 356 | |
| | 357 | public static synchronized NotificationManager getInstance() { |
| | 358 | if (instance == null) { |
| | 359 | instance = new NotificationManager(); |
| | 360 | } |
| | 361 | return instance; |
| | 362 | } |
| 373 | 363 | } |