Jpopupmenu Bug/Glitch When Showing Submenu

Davide Perini perini.davide at dpsoftware.org
Wed May 25 16:28:13 UTC 2022


I opened a bug report but they closed it by saying that they can't 
reproduce.
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8286713

They test on Windows 10, can this be the cause why they are not able to 
reproduce?

Here a gist where the code is better formatted.
https://gist.github.com/sblantipodi/4ed1d3acc04fd6d4f87c00c7e91eb343

This is the glitch I have, better described on a video:
https://www.youtube.com/shorts/IYq_yHemsgA

Using Adopt Open JDK 17, JavaFX 18.0.1 and Windows 11.

If I remove the submenu, problem is solved but I need the submenu.

Any idea?

Thanks
Davide


Il 09/05/2022 18:14, Davide Perini ha scritto:
> I add a video that shows the issue.
> https://www.youtube.com/shorts/IYq_yHemsgA
>
> as you can see, there is no issue until I put the mouse pointer over 
> the JMenu (submenu),
> once I put the mouse on the JMenu the entire JPopupMenu shows the glitch.
>
> Thanks
> Davide
>
> Il 09/05/2022 18:04, Davide Perini ha scritto:
>> I can't load images unfortunantly but this is the minimum code to 
>> reproduce the issue.
>> It seems that there is no way to add JMenu to JPopupMenu without 
>> having this glitch.
>>
>> Is this a problem in JavaFX?
>> I see non obvious errors in my code.
>>
>> Thanks
>> Davide
>>
>> package org.dpsoftware; import org.dpsoftware.config.Constants; 
>> import org.dpsoftware.utilities.CommonUtility; import javax.swing.*; 
>> import java.awt.*; import java.awt.event.*; import 
>> java.io.IOException; import java.io.PrintWriter; import 
>> java.io.Serial; import java.io.StringWriter; import java.net.URI; 
>> import java.net.URISyntaxException; public class TrayIconMainClass {
>>
>>    private static final StringTRAY_ICON_SKELETON_PROJECT_URL 
>> ="https://github.com/Sylvain-Bugat/tray-icon-skeleton"; /** Load the 
>> tray icon image to display in the tray bar*/ private static 
>> ImageTRAY_ICON_IMAGE = Toolkit.getDefaultToolkit().getImage( 
>> TrayIconMainClass.class.getClassLoader().getResource("tray_play.png" 
>> ) ); //$NON-NLS-1$ static JMenuaspectRatioSubMenu; /** * Main program 
>> launched in the jar file * * @param args * @throws IOException */ 
>> private void initializeImages() {
>>       // load an image }
>>
>>    public static void main(final String args[] )throws IOException {
>>       aspectRatioSubMenu =new JMenu("dadsdsa"); JMenuItem menuItam 
>> =new JMenuItem("dada"); aspectRatioSubMenu.add(menuItam); //Test if 
>> the system support the system tray if( SystemTray.isSupported() ) {
>>
>>          //Try to use the system Look&Feel try {
>>             UIManager.setLookAndFeel( 
>> UIManager.getCrossPlatformLookAndFeelClassName() ); }
>>          catch(final ClassNotFoundException exception ) {
>>             //If System Look&Feel is not supported, stay with the 
>> default one }
>>          catch(final InstantiationException exception ) {
>>             //If System Look&Feel is not supported, stay with the 
>> default one }
>>          catch(final IllegalAccessException exception ) {
>>             //If System Look&Feel is not supported, stay with the 
>> default one }
>>          catch(final UnsupportedLookAndFeelException exception ) {
>>             //If System Look&Feel is not supported, stay with the 
>> default one }
>>
>>          //Add the icon to the system tray final TrayIcon trayIcon 
>> =new TrayIcon(TRAY_ICON_IMAGE, "Tray icon skeleton" ); 
>> trayIcon.setImageAutoSize(true ); // Get the system default browser 
>> to open execution details final Desktop desktop = 
>> Desktop.getDesktop(); //Action listener to get click on top menu 
>> items final ActionListener menuListener =new ActionListener() {
>>             @SuppressWarnings("synthetic-access")
>>             public void actionPerformed(final ActionEvent e) {
>>
>>                if( JMenuItem.class.isInstance( e.getSource() ) ){
>>
>>                   JMenuItem jMenuItem = (JMenuItem) e.getSource(); 
>> JOptionPane.showMessageDialog(null, "It works, you clicked on:" + 
>> System.lineSeparator() + jMenuItem.getText(), "Your skill is 
>> great!!", JOptionPane.INFORMATION_MESSAGE ); //$NON-NLS-1$ }
>>             }
>>          }; //About menu listener final ActionListener aboutListener 
>> =new ActionListener() {
>>             @SuppressWarnings("synthetic-access")
>>             public void actionPerformed(final ActionEvent e) {
>>
>>                //Open an URL using the system default browser try {
>>                   final URI executionURI =new 
>> URI(TRAY_ICON_SKELETON_PROJECT_URL ); desktop.browse( executionURI ); }
>>                catch(final URISyntaxException exception ) {
>>
>>                   final StringWriter stringWriter =new 
>> StringWriter(); exception.printStackTrace(new PrintWriter( 
>> stringWriter ) ); JOptionPane.showMessageDialog(null, 
>> exception.getMessage() + System.lineSeparator() + 
>> stringWriter.toString(), "Tray icon skeleton redirection error", 
>> JOptionPane.ERROR_MESSAGE ); //$NON-NLS-1$ }
>>                catch(final IOException exception ) {
>>
>>                   final StringWriter stringWriter =new 
>> StringWriter(); exception.printStackTrace(new PrintWriter( 
>> stringWriter ) ); JOptionPane.showMessageDialog(null, 
>> exception.getMessage() + System.lineSeparator() + 
>> stringWriter.toString(), "Tray icon skeleton redirection error", 
>> JOptionPane.ERROR_MESSAGE ); //$NON-NLS-1$ }
>>             }
>>          }; //Get the system tray final SystemTray tray = 
>> SystemTray.getSystemTray(); //Tray icon skeleton exit listener final 
>> ActionListener exitListener =new ActionListener() {
>>             @SuppressWarnings("synthetic-access")
>>             public void actionPerformed(final ActionEvent e) {
>>                //Important: remove the icon from the tray to dispose 
>> it tray.remove(trayIcon ); System.exit(0 ); }
>>          }; //Popup menu 
>> JPopupMenu.setDefaultLightWeightPopupEnabled(false ); final 
>> JPopupMenu popupMenu =new JPopupMenu(); //Add 10 menu items for(int i 
>> =0 ; i <10 ; i++ ){
>>
>>             final JMenuItem jMenuItem =new JMenuItem("menu item " + i 
>> ); popupMenu.add( jMenuItem ); jMenuItem.addActionListener( 
>> menuListener ); System.out.println("DAD"); }
>>
>>          //Adding some menu separator popupMenu.addSeparator(); final 
>> JMenuItem aboutItem =new JMenuItem("About Tray icon skeleton" ); 
>> //$NON-NLS-1$ popupMenu.add( aboutItem ); 
>> aboutItem.addActionListener( aboutListener ); //Adding some menu 
>> separator popupMenu.addSeparator(); //Quit menu to terminate the tray 
>> icon by disposing the tray icon final JMenuItem exitItem =new 
>> JMenuItem("Quit" ); //$NON-NLS-1$ popupMenu.add( exitItem ); 
>> exitItem.addActionListener( exitListener ); //Hidden dialog displayed 
>> behing the system tray to auto hide the popup menu when clicking 
>> somewhere else on the screen final JDialog hiddenDialog =new JDialog 
>> (); hiddenDialog.setSize(1000, 1000 ); //Listener based on the focus 
>> to auto hide the hidden dialog and the popup menu when the hidden 
>> dialog box lost focus hiddenDialog.addWindowFocusListener(new 
>> WindowFocusListener() {
>>
>>             public void windowLostFocus (final WindowEvent e ) {
>>                hiddenDialog.setVisible(false ); }
>>
>>             public void windowGainedFocus (final WindowEvent e ) {
>>                //Nothing to do }
>>          }); popupMenu.add(aspectRatioSubMenu); //Add a listener to 
>> display the popupmenu and the hidden dialog box when the tray icon is 
>> clicked trayIcon.addMouseListener(new MouseAdapter() {
>>
>>             public void mouseReleased(final MouseEvent e) {
>>
>>                if( e.isPopupTrigger() ) {
>>                   //Display the menu at the position of the mouse 
>> //The dialog is also displayed at this position but it is behind the 
>> system tray popupMenu.setLocation( e.getX(), e.getY() ); 
>> hiddenDialog.setLocation( e.getX(), e.getY() ); //Important: set the 
>> hidden dialog as the invoker to hide the menu with this dialog lost 
>> focus popupMenu.setInvoker(hiddenDialog ); 
>> hiddenDialog.setVisible(true ); popupMenu.setVisible(true ); }
>>             }
>>          }); //Add the icon to the system tray try {
>>             tray.add( trayIcon ); }
>>          catch (final AWTException e ) {
>>
>>             final StringWriter stringWriter =new StringWriter(); 
>> e.printStackTrace(new PrintWriter( stringWriter ) ); 
>> JOptionPane.showMessageDialog(null, "tray icon cannot be added to the 
>> system tray" + System.lineSeparator() + e.getMessage() + 
>> System.lineSeparator() + stringWriter.toString(), "Tray icon skeleton 
>> initialization error", JOptionPane.ERROR_MESSAGE ); //$NON-NLS-1$ 
>> System.exit(2 ); }
>>       }
>>       else {
>>          //if the System is not compatible with SystemTray 
>> JOptionPane.showMessageDialog(null, "SystemTray cannot be 
>> initialized" + System.lineSeparator() +"this system is not 
>> compatible!", "Tray icon skeleton initialization error", 
>> JOptionPane.ERROR_MESSAGE ); //$NON-NLS-1$ //$NON-NLS-2$ 
>> System.exit(1 ); }
>>
>>    }
>> }
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> Il 08/05/2022 01:26, Davide Perini ha scritto:
>>> Hi all,
>>> I'm using a JPopupMenu to workaround the lack of a "real tray icon" 
>>> in JavaFX.
>>>
>>> This is the simple code I'm using:
>>> https://github.com/Sylvain-Bugat/tray-icon-skeleton/blob/master/src/main/java/com/github/sbugat/trayiconskeleton/TrayIconMainClass.java 
>>>
>>>
>>> It all works well until I add a submenu (JMenu) to my JPopupMenu.
>>>
>>> This is how the tray looks when no glitch appear:
>>>
>>>
>>> and this is the tray how looks like when the glitch of the submenu 
>>> appers:
>>>
>>>
>>>
>>>
>>> to trigger the glitch I can simply move the mouse over the submenu 
>>> and then move the mouse over the other jmenuitem.
>>>
>>> Any idea on why I have this error?
>>>
>>> Thanks
>>> Davide
>



More information about the openjfx-dev mailing list