001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.frame.progress;
020
021import icy.gui.frame.IcyFrame;
022import icy.gui.util.GuiUtil;
023import icy.network.NetworkUtil;
024import icy.preferences.GeneralPreferences;
025import icy.system.thread.ThreadUtil;
026import icy.util.StringUtil;
027
028import java.awt.BorderLayout;
029import java.awt.Dimension;
030import java.awt.Font;
031import java.awt.event.MouseAdapter;
032import java.awt.event.MouseEvent;
033import java.util.List;
034import java.util.Timer;
035import java.util.TimerTask;
036
037import javax.swing.Box;
038import javax.swing.JCheckBox;
039import javax.swing.JEditorPane;
040import javax.swing.UIManager;
041import javax.swing.event.HyperlinkEvent;
042import javax.swing.event.HyperlinkListener;
043import javax.swing.text.html.HTMLDocument;
044
045/**
046 * @author Stephane
047 */
048public class ToolTipFrame extends TaskFrame
049{
050    Timer timer;
051    JEditorPane editorPane;
052    JCheckBox doNotDisplayCheckbox;
053
054    final int liveTime;
055    final String id;
056
057    /**
058     * Show an tool tip with specified parameters
059     * 
060     * @param message
061     *        message to display in tool tip
062     * @param liveTime
063     *        life time in second (0 = infinite)
064     * @param id
065     *        toolTip id, it's used to display the "Do not display in future" checkbox<br>
066     *        and remember its value
067     */
068    public ToolTipFrame(final String message, int liveTime, String id)
069    {
070        super();
071
072        this.liveTime = liveTime;
073        this.id = id;
074
075        if (!StringUtil.isEmpty(id))
076        {
077            // tool tip should not be displayed ?
078            if (!GeneralPreferences.getPreferencesToolTips().getBoolean(id, true) || alreadyExist(id))
079            {
080                // close and exit
081                close();
082                return;
083            }
084        }
085
086        if (liveTime != 0)
087        {
088            timer = new Timer("ToolTip timer");
089            timer.schedule(new TimerTask()
090            {
091                @Override
092                public void run()
093                {
094                    // EDT safe
095                    doClose();
096                }
097            }, liveTime * 1000);
098        }
099
100        ThreadUtil.invokeLater(new Runnable()
101        {
102            @Override
103            public void run()
104            {
105                editorPane = new JEditorPane("text/html", message);
106                editorPane.setMinimumSize(new Dimension(240, 60));
107                editorPane.setEditable(false);
108                editorPane.setToolTipText("Click to close the tool tip");
109                // set same font as JLabel for JEditorPane
110                final Font font = UIManager.getFont("Label.font");
111                final String bodyRule = "body { font-family: " + font.getFamily() + "; " + "font-size: "
112                        + font.getSize() + "pt; }";
113                ((HTMLDocument) editorPane.getDocument()).getStyleSheet().addRule(bodyRule);
114                editorPane.addMouseListener(new MouseAdapter()
115                {
116                    @Override
117                    public void mouseClicked(MouseEvent e)
118                    {
119                        doClose();
120                    }
121                });
122                // support link click
123                editorPane.addHyperlinkListener(new HyperlinkListener()
124                {
125                    @Override
126                    public void hyperlinkUpdate(HyperlinkEvent e)
127                    {
128                        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
129                        {
130                            NetworkUtil.openBrowser(e.getURL());
131                        }
132                    }
133                });
134
135                doNotDisplayCheckbox = new JCheckBox("Do not display again", false);
136                doNotDisplayCheckbox.setToolTipText("Do not display this tooltip the next time");
137
138                mainPanel.setLayout(new BorderLayout());
139
140                mainPanel.add(editorPane, BorderLayout.CENTER);
141                if (!StringUtil.isEmpty(ToolTipFrame.this.id))
142                    mainPanel.add(GuiUtil.createLineBoxPanel(doNotDisplayCheckbox, Box.createHorizontalGlue()),
143                            BorderLayout.SOUTH);
144                pack();
145            }
146        });
147    }
148
149    /**
150     * Show an tool tip with specified message
151     * 
152     * @param message
153     *        message to display in tool tip
154     * @param id
155     *        toolTip id, it's used to display the "Do not display in future" checkbox<br>
156     *        and remember its value
157     */
158    public ToolTipFrame(String message, String id)
159    {
160        this(message, 0, id);
161    }
162
163    /**
164     * Show an tool tip with specified message
165     * 
166     * @param message
167     *        message to display in tool tip
168     * @param liveTime
169     *        life time in second (0 = infinite)
170     */
171    public ToolTipFrame(String message, int liveTime)
172    {
173        this(message, liveTime, "");
174    }
175
176    /**
177     * Show an tool tip with specified message
178     * 
179     * @param message
180     *        message to display in tool tip
181     */
182    public ToolTipFrame(String message)
183    {
184        this(message, 0, "");
185    }
186
187    /**
188     * Return true if a tooltip with the same is is already active
189     */
190    private boolean alreadyExist(String id)
191    {
192        final List<IcyFrame> frames = IcyFrame.getAllFrames(ToolTipFrame.class);
193
194        for (IcyFrame f : frames)
195            if ((f != this) && ((ToolTipFrame) f).id.equals(id))
196                return true;
197
198        return false;
199    }
200
201    void doClose()
202    {
203        // save display flag only if set to false
204        if (!StringUtil.isEmpty(id) && doNotDisplayCheckbox.isSelected())
205            GeneralPreferences.getPreferencesToolTips().putBoolean(id, false);
206
207        close();
208    }
209
210    public void setText(final String text)
211    {
212        ThreadUtil.invokeLater(new Runnable()
213        {
214            @Override
215            public void run()
216            {
217                editorPane.setText(text);
218                pack();
219            }
220        });
221    }
222
223    @Override
224    public void internalClose()
225    {
226        // stop timer
227        if (timer != null)
228            timer.cancel();
229
230        super.internalClose();
231    }
232
233}