/* * This file is part of Arduino. * * Arduino is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * As a special exception, you may use this file as part of a free software * library without restriction. Specifically, if other files instantiate * templates or use macros or inline functions from this file, or you compile * this file and link it with other files to produce an executable, this * file does not by itself cause the resulting executable to be covered by * the GNU General Public License. This exception does not however * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. * * Copyright 2015 Arduino LLC (http://www.arduino.cc/) */ package cc.arduino.view; import cc.arduino.Constants; import processing.app.Base; import processing.app.BaseNoGui; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.awt.*; import java.awt.event.*; import java.nio.file.Paths; public class NotificationPopup extends JDialog { private final ComponentAdapter parentMovedListener; private final Timer autoCloseAfterTimeout; public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, String titleText, String message) { super(parent, false); initComponents(); updateLocation(parent); parentMovedListener = new ComponentAdapter() { @Override public void componentMoved(ComponentEvent e) { updateLocation(parent); } }; parent.addComponentListener(parentMovedListener); title.setText(titleText); text.setText("" + message.replace("\n", "
") + ""); text.addHyperlinkListener(hyperlinkListener); addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { parent.removeComponentListener(parentMovedListener); } }); autoCloseAfterTimeout = new Timer(Constants.NOTIFICATION_POPUP_AUTOCLOSE_DELAY, (e) -> close()); autoCloseAfterTimeout.start(); text.addHyperlinkListener(e -> { if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { return; } close(); }); Base.registerWindowCloseKeys(getRootPane(), e -> close()); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { close(); } }); } private void updateLocation(Frame parent) { Point parentLocation = parent.getLocation(); int parentX = Double.valueOf(parentLocation.getX()).intValue(); int parentY = Double.valueOf(parentLocation.getY()).intValue(); setLocation(parentX + parent.getWidth() - getWidth(), parentY + parent.getHeight() - getHeight()); } public void close() { if (autoCloseAfterTimeout.isRunning()) { autoCloseAfterTimeout.stop(); } dispatchEvent(new WindowEvent(NotificationPopup.this, WindowEvent.WINDOW_CLOSING)); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { title = new javax.swing.JLabel(); javax.swing.JLabel jLabel1 = new javax.swing.JLabel(); text = new javax.swing.JEditorPane(); closeButton = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setAlwaysOnTop(true); setFocusable(false); setFocusableWindowState(false); setUndecorated(true); setResizable(false); title.setFont(title.getFont().deriveFont(title.getFont().getStyle() | java.awt.Font.BOLD)); jLabel1.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "arduino_small.png").toFile().getAbsolutePath())); text.setEditable(false); text.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 0, true)); text.setContentType("text/html"); // NOI18N text.setOpaque(false); closeButton.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "theme", "close.png").toFile().getAbsolutePath())); closeButton.setBorder(null); closeButton.setBorderPainted(false); closeButton.setHideActionText(true); closeButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { closeButtonActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, 264, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) .addGroup(layout.createSequentialGroup() .addComponent(title, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(24, 24, 24) .addComponent(closeButton)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(title)) .addComponent(closeButton)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// //GEN-END:initComponents private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed close(); }//GEN-LAST:event_closeButtonActionPerformed /** * @param args the command line arguments */ public static void main(String args[]) { /* Create and display the dialog */ EventQueue.invokeLater(new Runnable() { public void run() { NotificationPopup dialog = new NotificationPopup(new JFrame(), System.out::println, "title", "test test test test test test test test test\n" + " test test test test test test test test test test test"); dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); dialog.setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton closeButton; private javax.swing.JEditorPane text; private javax.swing.JLabel title; // End of variables declaration//GEN-END:variables }