001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2025
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas/
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see https://www.gnu.org/licenses/.
027 */
028
029package edu.wisc.ssec.mcidasv.ui;
030
031import javax.swing.JFrame;
032import javax.swing.JPanel;
033import javax.swing.JWindow;
034
035import java.awt.Color;
036import java.awt.Font;
037import java.awt.Graphics;
038
039import org.slf4j.Logger;
040import org.slf4j.LoggerFactory;
041
042public class PopupMessage extends JFrame {
043
044    /** Logger for debugging*/
045    private static final Logger logger = LoggerFactory.getLogger(PopupMessage.class);
046
047    /** Window used to create the toast */
048    private JWindow w = null;
049
050    /** Date Refresh Spec */
051    private final String DATA_REFRESH= "DataRefresh";
052
053    /** Example Spec */
054    private final String EXAMPLE_REFRESH = "ExampleSpec";
055
056
057    /**
058     * Creates a toast with the given message at the specific point on the screen
059     * (x, y) with the given specification; there is no default
060     * @param s message string
061     * @param x screen position x
062     * @param y screen position y
063     * @param spec toast specification
064     */
065
066    public PopupMessage(String s, int x, int y, String spec) {
067        w = new JWindow();
068        w.setAlwaysOnTop(true);
069        w.setBackground(new Color(0, 0, 0, 0));
070
071
072        JPanel p = new JPanel() {
073            public void paintComponent(Graphics g) {
074                if (spec.equals(DATA_REFRESH)) {
075                    int wid = g.getFontMetrics().stringWidth(s) * 2;
076                    int hei = g.getFontMetrics().getHeight() * 2;
077
078                    g.setColor(Color.WHITE);
079                    g.fillRect(10, 10, wid + 30, hei + 10);
080                    g.setColor(Color.BLACK);
081                    g.drawRect(10, 10, wid + 30, hei + 10);
082
083                    g.setColor(Color.BLACK);
084                    Font McvFont = new Font("Arial", Font.PLAIN, 14);
085                    g.setFont(McvFont);
086                    g.drawString(s, (wid / 4) + 25, hei + 3);
087                    g.setColor(Color.GRAY);
088                    McvFont = new Font("Arial", Font.PLAIN, 10);
089                    g.setFont(McvFont);
090                    g.drawString("McIDAS-V", 15, 22);
091
092                    int t = 250;
093                    for (int i = 0; i < 4; i++) {
094                        t -= 60;
095                        g.setColor(new Color(0, 0, 0, t));
096                        g.drawRect(10 - i, 10 - i, wid + 30 + i * 2,
097                                hei + 10 + i * 2);
098                    }
099
100                } else if (spec.equals(EXAMPLE_REFRESH)) {
101                    // TODO: if other specifications for toasts are needed, add them as branches in this if/else statement
102                    // one size WILL NOT fit all
103
104                    int wid = g.getFontMetrics().stringWidth("Example Toast") * 2;
105                    int hei = g.getFontMetrics().getHeight() * 2;
106
107                    // Font style, color, and size for the main message
108                    g.setColor(Color.BLACK);
109                    Font McvFont = new Font("Arial", Font.PLAIN, 14);
110                    g.setFont(McvFont);
111
112                    // Main message text
113                    g.drawString("Example Toast", (wid / 4) + 25, hei + 3);
114
115                    // Font style, color, and size for the McIDAS-V header in the top left
116                    g.setColor(Color.GRAY);
117                    McvFont = new Font("Arial", Font.PLAIN, 10);
118                    g.setFont(McvFont);
119                    g.drawString("McIDAS-V", 15, 22);
120
121                    int t = 250;
122                    for (int i = 0; i < 4; i++) {
123                        t -= 60;
124                        g.setColor(new Color(0, 0, 0, t));
125                        g.drawRect(10 - i, 10 - i, wid + 30 + i * 2,
126                                hei + 10 + i * 2);
127                    }
128
129                } else {
130                    logger.error("Toast spec is not valid");
131                    // If a valid toast spec is not specified, nothing will be made or displayed
132                    return;
133                }
134            }
135        };
136
137        w.add(p);
138        w.setLocation(x, y);
139
140        // TODO: set the dimensions as tightly as possible if you want to avoid a grey background
141        if (spec.equals(DATA_REFRESH)) {
142            w.setSize(220, 65);
143        } else if (spec.equals(EXAMPLE_REFRESH)) {
144            w.setSize(220, 65);
145        } else {
146            logger.error("Notification spec is not valid");
147        }
148    }
149
150    /**
151     * Displays the toast
152     * @param timeAlive time the toast remains visible
153     */
154
155    public void showPopupMessage(Integer timeAlive) {
156        try {
157            w.setOpacity(1);
158            w.setVisible(true);
159
160            Thread.sleep(timeAlive);
161
162            for (double d = 1.0; d > 0.2; d -= 0.05) {
163                Thread.sleep(50);
164                w.setOpacity((float)d);
165            }
166            w.setVisible(false);
167        } catch (Exception e) { logger.error(e.getMessage());}
168    }
169}