Jpopupmenu Bug/Glitch When Showing Submenu

Davide Perini perini.davide at dpsoftware.org
Mon May 9 16:14:11 UTC 2022


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