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