< prev index next >

src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 23,52 **** * questions. */ package sun.lwawt.macosx; ! import sun.awt.AWTAccessor; ! import sun.awt.SunToolkit; ! ! import javax.swing.*; ! import java.awt.*; ! import java.awt.event.*; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.awt.peer.TrayIconPeer; - import java.beans.PropertyChangeEvent; - import java.beans.PropertyChangeListener; - import java.util.concurrent.atomic.AtomicReference; ! import static sun.awt.AWTAccessor.*; public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { private TrayIcon target; private PopupMenu popup; - private JDialog messageDialog; - private DialogEventHandler handler; // In order to construct MouseEvent object, we need to specify a // Component target. Because TrayIcon isn't Component's subclass, // we use this dummy frame instead private final Frame dummyFrame; --- 23,63 ---- * questions. */ package sun.lwawt.macosx; ! import java.awt.AWTEvent; ! import java.awt.Button; ! import java.awt.Frame; ! import java.awt.Graphics2D; ! import java.awt.GraphicsConfiguration; ! import java.awt.GraphicsDevice; ! import java.awt.GraphicsEnvironment; ! import java.awt.Image; ! import java.awt.MediaTracker; ! import java.awt.PopupMenu; ! import java.awt.RenderingHints; ! import java.awt.Toolkit; ! import java.awt.Transparency; ! import java.awt.TrayIcon; ! import java.awt.event.ActionEvent; ! import java.awt.event.MouseEvent; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.awt.peer.TrayIconPeer; ! import javax.swing.Icon; ! import javax.swing.UIManager; ! ! import sun.awt.SunToolkit; ! ! import static sun.awt.AWTAccessor.MenuComponentAccessor; ! import static sun.awt.AWTAccessor.getMenuComponentAccessor; public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { private TrayIcon target; private PopupMenu popup; // In order to construct MouseEvent object, we need to specify a // Component target. Because TrayIcon isn't Component's subclass, // we use this dummy frame instead private final Frame dummyFrame;
*** 57,68 **** private static int mouseClickButtons = 0; CTrayIcon(TrayIcon target) { super(0, true); - this.messageDialog = null; - this.handler = null; this.target = target; this.popup = target.getPopupMenu(); this.dummyFrame = new Frame(); setPtr(createModel()); --- 68,77 ----
*** 127,158 **** * kind of window in Lion, NSPopover, so perhaps it could be used it * to implement better looking notifications. */ public void displayMessage(final String caption, final String text, final String messageType) { ! ! if (SwingUtilities.isEventDispatchThread()) { ! displayMessageOnEDT(caption, text, messageType); ! } else { ! try { ! SwingUtilities.invokeAndWait(new Runnable() { ! public void run() { ! displayMessageOnEDT(caption, text, messageType); } }); ! } catch (Exception e) { ! throw new AssertionError(e); ! } } } @Override public void dispose() { - if (messageDialog != null) { - disposeMessageDialog(); - } - dummyFrame.dispose(); if (popup != null) { popup.removeNotify(); } --- 136,164 ---- * kind of window in Lion, NSPopover, so perhaps it could be used it * to implement better looking notifications. */ public void displayMessage(final String caption, final String text, final String messageType) { ! // obtain icon to show along the message ! Icon icon = getIconForMessageType(messageType); ! CImage cimage = null; ! if (icon != null) { ! BufferedImage image = scaleIcon(icon, 0.75); ! cimage = CImage.getCreator().createFromImage(image); } + if (cimage != null) { + cimage.execute(imagePtr -> { + execute(ptr -> nativeShowNotification(ptr, caption, text, + imagePtr)); }); ! } else { ! execute(ptr -> nativeShowNotification(ptr, caption, text, 0)); } } @Override public void dispose() { dummyFrame.dispose(); if (popup != null) { popup.removeNotify(); }
*** 274,431 **** mouseClickButtons &= ~eventButtonMask; } } ! private native Point2D nativeGetIconLocation(long trayIconModel); ! ! public void displayMessageOnEDT(String caption, String text, ! String messageType) { ! if (messageDialog != null) { ! disposeMessageDialog(); ! } ! ! // obtain icon to show along the message ! Icon icon = getIconForMessageType(messageType); ! if (icon != null) { ! icon = new ImageIcon(scaleIcon(icon, 0.75)); ! } ! ! // We want the message dialog text area to be about 1/8 of the screen ! // size. There is nothing special about this value, it's just makes the ! // message dialog to look nice ! Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); ! int textWidth = screenSize.width / 8; ! ! // create dialog to show ! messageDialog = createMessageDialog(caption, text, textWidth, icon); ! ! // finally, show the dialog to user ! showMessageDialog(); ! } /** ! * Creates dialog window used to display the message */ ! private JDialog createMessageDialog(String caption, String text, ! int textWidth, Icon icon) { ! JDialog dialog; ! handler = new DialogEventHandler(); ! ! JTextArea captionArea = null; ! if (caption != null) { ! captionArea = createTextArea(caption, textWidth, false, true); ! } ! ! JTextArea textArea = null; ! if (text != null){ ! textArea = createTextArea(text, textWidth, true, false); ! } ! ! Object[] panels = null; ! if (captionArea != null) { ! if (textArea != null) { ! panels = new Object[] {captionArea, new JLabel(), textArea}; ! } else { ! panels = new Object[] {captionArea}; ! } ! } else { ! if (textArea != null) { ! panels = new Object[] {textArea}; ! } ! } ! ! // We want message dialog with small title bar. There is a client ! // property property that does it, however, it must be set before ! // dialog's native window is created. This is why we create option ! // pane and dialog separately ! final JOptionPane op = new JOptionPane(panels); ! op.setIcon(icon); ! op.addPropertyChangeListener(handler); ! ! // Make Ok button small. Most likely won't work for L&F other then Aqua ! try { ! JPanel buttonPanel = (JPanel)op.getComponent(1); ! JButton ok = (JButton)buttonPanel.getComponent(0); ! ok.putClientProperty("JComponent.sizeVariant", "small"); ! } catch (Throwable t) { ! // do nothing, we tried and failed, no big deal ! } ! ! dialog = new JDialog((Dialog) null); ! JRootPane rp = dialog.getRootPane(); ! ! // gives us dialog window with small title bar and not zoomable ! rp.putClientProperty(CPlatformWindow.WINDOW_STYLE, "small"); ! rp.putClientProperty(CPlatformWindow.WINDOW_ZOOMABLE, "false"); ! ! dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); ! dialog.setModal(false); ! dialog.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE); ! dialog.setAlwaysOnTop(true); ! dialog.setAutoRequestFocus(false); ! dialog.setResizable(false); ! dialog.setContentPane(op); ! ! dialog.addWindowListener(handler); ! ! // suppress security warning for untrusted windows ! AWTAccessor.getWindowAccessor().setTrayIconWindow(dialog, true); ! ! dialog.pack(); ! ! return dialog; ! } ! ! private void showMessageDialog() { ! ! Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); ! AtomicReference<Point2D> ref = new AtomicReference<>(); ! execute(ptr -> { ! ref.set(nativeGetIconLocation(ptr)); ! }); ! Point2D iconLoc = ref.get(); ! if (iconLoc == null) { ! return; ! } ! ! int dialogY = (int)iconLoc.getY(); ! int dialogX = (int)iconLoc.getX(); ! if (dialogX + messageDialog.getWidth() > screenSize.width) { ! dialogX = screenSize.width - messageDialog.getWidth(); ! } ! ! messageDialog.setLocation(dialogX, dialogY); ! messageDialog.setVisible(true); ! } ! ! private void disposeMessageDialog() { ! if (SwingUtilities.isEventDispatchThread()) { ! disposeMessageDialogOnEDT(); ! } else { ! try { ! SwingUtilities.invokeAndWait(new Runnable() { ! public void run() { ! disposeMessageDialogOnEDT(); ! } ! }); ! } catch (Exception e) { ! throw new AssertionError(e); ! } ! } ! } ! ! private void disposeMessageDialogOnEDT() { ! if (messageDialog != null) { ! messageDialog.removeWindowListener(handler); ! messageDialog.removePropertyChangeListener(handler); ! messageDialog.dispose(); ! ! messageDialog = null; ! handler = null; ! } ! } /** * Scales an icon using specified scale factor * * @param icon icon to scale --- 280,297 ---- mouseClickButtons &= ~eventButtonMask; } } ! private native void nativeShowNotification(long trayIconModel, ! String caption, String text, ! long nsimage); /** ! * Used by the automated tests. */ ! private native Point2D nativeGetIconLocation(long trayIconModel); /** * Scales an icon using specified scale factor * * @param icon icon to scale
*** 478,535 **** } else { // this is just an application icon return UIManager.getIcon("OptionPane.informationIcon"); } } - - private static JTextArea createTextArea(String text, int width, - boolean isSmall, boolean isBold) { - JTextArea textArea = new JTextArea(text); - - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - textArea.setEditable(false); - textArea.setFocusable(false); - textArea.setBorder(null); - textArea.setBackground(new JLabel().getBackground()); - - if (isSmall) { - textArea.putClientProperty("JComponent.sizeVariant", "small"); - } - - if (isBold) { - Font font = textArea.getFont(); - Font boldFont = new Font(font.getName(), Font.BOLD, font.getSize()); - textArea.setFont(boldFont); - } - - textArea.setSize(width, 1); - - return textArea; - } - - /** - * Implements all the Listeners needed by message dialog - */ - private final class DialogEventHandler extends WindowAdapter - implements PropertyChangeListener { - - public void windowClosing(WindowEvent we) { - disposeMessageDialog(); - } - - public void propertyChange(PropertyChangeEvent e) { - if (messageDialog == null) { - return; - } - - String prop = e.getPropertyName(); - Container cp = messageDialog.getContentPane(); - - if (messageDialog.isVisible() && e.getSource() == cp && - (prop.equals(JOptionPane.VALUE_PROPERTY))) { - disposeMessageDialog(); - } - } - } } --- 344,350 ----
< prev index next >