< prev index next >
test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java
Print this page
*** 21,63 ****
* questions.
*/
/*
@test
! @bug 8007220
! @summary Reference to the popup leaks after the TrayIcon is removed
! @author Petr Pchelko
! @library ../../../../lib/testlibrary/
! @build ExtendedRobot
@run main/othervm -Xmx50m PopupMenuLeakTest
*/
! import java.awt.*;
! import javax.swing.SwingUtilities;
!
import java.awt.image.BufferedImage;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
public class PopupMenuLeakTest {
! static final AtomicReference<WeakReference<TrayIcon>> iconWeakReference = new AtomicReference<>();
! static final AtomicReference<WeakReference<PopupMenu>> popupWeakReference = new AtomicReference<>();
! static ExtendedRobot robot;
public static void main(String[] args) throws Exception {
- robot = new ExtendedRobot();
SwingUtilities.invokeAndWait(PopupMenuLeakTest::createSystemTrayIcon);
! sleep();
! // To make the test automatic we explicitly call addNotify on a popup to create the peer
SwingUtilities.invokeAndWait(PopupMenuLeakTest::addNotifyPopup);
- sleep();
SwingUtilities.invokeAndWait(PopupMenuLeakTest::removeIcon);
! sleep();
! assertCollected(popupWeakReference.get(), "Failed, reference to popup not collected");
! assertCollected(iconWeakReference.get(), "Failed, reference to tray icon not collected");
}
private static void addNotifyPopup() {
PopupMenu menu = popupWeakReference.get().get();
if (menu == null) {
--- 21,69 ----
* questions.
*/
/*
@test
! @bug 8007220 8039081
! @summary Reference to the popup should not leak after the TrayIcon is
! removed from system tray.
@run main/othervm -Xmx50m PopupMenuLeakTest
*/
! import java.awt.Color;
! import java.awt.Frame;
! import java.awt.Graphics2D;
! import java.awt.Image;
! import java.awt.MenuItem;
! import java.awt.PopupMenu;
! import java.awt.RenderingHints;
! import java.awt.SystemTray;
! import java.awt.TrayIcon;
import java.awt.image.BufferedImage;
+ import javax.swing.SwingUtilities;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
public class PopupMenuLeakTest {
! static final AtomicReference<WeakReference<TrayIcon>> iconWeakReference
! = new AtomicReference<>();
! static final AtomicReference<WeakReference<PopupMenu>> popupWeakReference
! = new AtomicReference<>();
! static Frame popupMenuParentFrame;
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(PopupMenuLeakTest::createSystemTrayIcon);
! // To automate the test, explicitly call addNotify on a popup
! // to create the peer.
SwingUtilities.invokeAndWait(PopupMenuLeakTest::addNotifyPopup);
SwingUtilities.invokeAndWait(PopupMenuLeakTest::removeIcon);
! assertCollected(popupWeakReference.get(),
! "Failed, reference to popup not collected");
! assertCollected(iconWeakReference.get(),
! "Failed, reference to tray icon not collected");
}
private static void addNotifyPopup() {
PopupMenu menu = popupWeakReference.get().get();
if (menu == null) {
*** 70,91 ****
TrayIcon icon = iconWeakReference.get().get();
if (icon == null) {
throw new RuntimeException("Failed: TrayIcon collected too early");
}
SystemTray.getSystemTray().remove(icon);
}
! private static void assertCollected(WeakReference<?> reference, String message) {
java.util.List<byte[]> bytes = new ArrayList<>();
- for (int i = 0; i < 5; i ++) {
try {
while (true) {
! bytes.add(new byte[1024]);
}
} catch (OutOfMemoryError err) {
- bytes = new ArrayList<>();
- }
}
if (reference.get() != null) {
throw new RuntimeException(message);
}
}
--- 76,99 ----
TrayIcon icon = iconWeakReference.get().get();
if (icon == null) {
throw new RuntimeException("Failed: TrayIcon collected too early");
}
SystemTray.getSystemTray().remove(icon);
+
+ PopupMenu menu = popupWeakReference.get().get();
+ popupMenuParentFrame.remove(menu);
+ popupMenuParentFrame.dispose();
}
! private static void assertCollected(WeakReference<?> reference,
! String message) {
java.util.List<byte[]> bytes = new ArrayList<>();
try {
while (true) {
! bytes.add(new byte[4096]);
}
} catch (OutOfMemoryError err) {
}
if (reference.get() != null) {
throw new RuntimeException(message);
}
}
*** 93,124 ****
private static void createSystemTrayIcon() {
final TrayIcon trayIcon = new TrayIcon(createTrayIconImage());
trayIcon.setImageAutoSize(true);
try {
! // Add tray icon to system tray *before* adding popup menu to demonstrate buggy behaviour
trayIcon.setPopupMenu(createTrayIconPopupMenu());
SystemTray.getSystemTray().add(trayIcon);
iconWeakReference.set(new WeakReference<>(trayIcon));
! popupWeakReference.set(new WeakReference<>(trayIcon.getPopupMenu()));
! } catch (final AWTException awte) {
! awte.printStackTrace();
}
}
private static Image createTrayIconImage() {
! /**
! * Create a small image of a red circle to use as the icon for the tray icon
! */
int trayIconImageSize = 32;
! final BufferedImage trayImage = new BufferedImage(trayIconImageSize, trayIconImageSize, BufferedImage.TYPE_INT_ARGB);
! final Graphics2D trayImageGraphics = (Graphics2D) trayImage.getGraphics();
! trayImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
trayImageGraphics.setColor(new Color(255, 255, 255, 0));
! trayImageGraphics.fillRect(0, 0, trayImage.getWidth(), trayImage.getHeight());
trayImageGraphics.setColor(Color.red);
int trayIconImageInset = 4;
trayImageGraphics.fillOval(trayIconImageInset,
--- 101,135 ----
private static void createSystemTrayIcon() {
final TrayIcon trayIcon = new TrayIcon(createTrayIconImage());
trayIcon.setImageAutoSize(true);
try {
! // Add tray icon to system tray *before* adding popup menu.
trayIcon.setPopupMenu(createTrayIconPopupMenu());
SystemTray.getSystemTray().add(trayIcon);
iconWeakReference.set(new WeakReference<>(trayIcon));
! popupWeakReference.set(new WeakReference<>(
! trayIcon.getPopupMenu()));
! } catch (final Exception ex) {
! ex.printStackTrace();
}
}
private static Image createTrayIconImage() {
! // Create a small red circle image to use as the icon for tray icon.
int trayIconImageSize = 32;
! final BufferedImage trayImage = new BufferedImage(trayIconImageSize,
! trayIconImageSize, BufferedImage.TYPE_INT_ARGB);
! final Graphics2D trayImageGraphics
! = (Graphics2D) trayImage.getGraphics();
! trayImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
! RenderingHints.VALUE_ANTIALIAS_ON);
trayImageGraphics.setColor(new Color(255, 255, 255, 0));
! trayImageGraphics.fillRect(0, 0, trayImage.getWidth(),
! trayImage.getHeight());
trayImageGraphics.setColor(Color.red);
int trayIconImageInset = 4;
trayImageGraphics.fillOval(trayIconImageInset,
*** 135,149 ****
return trayImage;
}
private static PopupMenu createTrayIconPopupMenu() {
final PopupMenu trayIconPopupMenu = new PopupMenu();
final MenuItem popupMenuItem = new MenuItem("TEST!");
trayIconPopupMenu.add(popupMenuItem);
- return trayIconPopupMenu;
- }
! private static void sleep() {
! robot.waitForIdle(100);
}
}
--- 146,161 ----
return trayImage;
}
private static PopupMenu createTrayIconPopupMenu() {
+ popupMenuParentFrame = new Frame();
+ popupMenuParentFrame.setVisible(true);
+
final PopupMenu trayIconPopupMenu = new PopupMenu();
final MenuItem popupMenuItem = new MenuItem("TEST!");
trayIconPopupMenu.add(popupMenuItem);
! popupMenuParentFrame.add(trayIconPopupMenu);
! return trayIconPopupMenu;
}
}
\ No newline at end of file
< prev index next >