Search code examples
javaswingjava-2djpopupmenu

JPanel inside PopupMenu


Is there a way to render graphics like JPanel in a PopupMenu (with TrayIcon)? I know it's possible by using JPopupMenu but I do not like that the popup doesn't close if I click outside of it (and the icon does not get highlighted as with PopupMenu).

Example of what I'm trying to do with JPopupMenu:

    if( SystemTray.isSupported() ) {
        // Get the SystemTray instance
        SystemTray tray = SystemTray.getSystemTray();

        // Load icon
        Image image = new ImageIcon(this.getClass().getResource("delete.png")).getImage();

        final JPopupMenu popup = new JPopupMenu();
        popup.add( new JMenuItem("Test") );

        JPanel p1 = new JPanel();
        p1.setBackground( Color.red );
        p1.setPreferredSize( new Dimension(200, 300) );
        popup.add( p1 );

        JTrayIcon trayIcon = new JTrayIcon( image );
        trayIcon.setJPopupMenu( popup );

        trayIcon.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                popup.setLocation(e.getX(), e.getY());
                popup.setInvoker(popup);
                popup.setVisible(true);
            }
        });

        try {
            tray.add( trayIcon );
        } catch (Exception e) {
            JOptionPane.showMessageDialog( null, "Could not add tray icon." );
        }
    }

Solution

  • You can extending JPopupMenu and add customItem to it:
    public class CustomPopUp extends JPopupMenu {
    
        public CustomPopUp() {
            reload();
        }
    
        private void reload(final Collection<CustomItem> items) throws BadLocationException {
            for (final CustomItem item : items) {
                add(new AbstractAction(item.getLabel(), item.getIcon()) {               
                    @Override
                    public void actionPerformed(final ActionEvent e) {
                        //do whatever
                    }
                });
            }
    
        }
    }
    public class CustomItem {
        private String label;
        private ImageIcon icon;
    
        //getter and setter
    }