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