Jpopupmenu Bug/Glitch When Showing Submenu
Davide Perini
perini.davide at dpsoftware.org
Mon May 9 16:04:16 UTC 2022
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