< 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 >