Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

log swing popup menu look and feel exception #32

Open
github-actions bot opened this issue Jan 4, 2021 · 0 comments
Open

log swing popup menu look and feel exception #32

github-actions bot opened this issue Jan 4, 2021 · 0 comments
Labels
todo Needs to be done todo-log TODO related to logging

Comments

@github-actions
Copy link

github-actions bot commented Jan 4, 2021

log swing popup menu look and feel exception

// TODO log swing popup menu look and feel exception

import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;

import javax.swing.JDialog;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

/**
 * Used to show and hide a Swing JPopupMenu when system tray icon is clicked.
 * 
 * @author Jonathan Henly
 */
public final class SwingPopupMenu extends TrayIconPopupMenu<JPopupMenu, JMenuItem> {
    // tray icon reference needed to add listeners to
    private TrayIcon trayIcon;
    // hidden dialog used to hide JPopupMenu when focus lost
    private JDialog hiddenDialog;
    
    
    /**************************************************************************
     *                                                                        *
     * Constructor(s)                                                         *
     *                                                                        *
     *************************************************************************/
    
    /**
     * Shows a JPopupMenu when system tray icon is clicked.
     * @param systemTrayIcon - the system tray icon
     */
    public SwingPopupMenu(TrayIcon systemTrayIcon) {
        super(new JPopupMenu());
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // TODO log swing popup menu look and feel exception
            System.err.println(e.getLocalizedMessage());
        }
        trayIcon = systemTrayIcon;
        
        createHiddenDialog();
        addTrayIconListeners();
        
        // ensure popup menu uses system look and feel
        SwingUtilities.updateComponentTreeUI(menu);
    }
    
    
    /**************************************************************************
     *                                                                        *
     * Private API                                                            *
     *                                                                        *
     *************************************************************************/
    
    /** Initialize the hidden dialog as a headless, titleless dialog window. */
    private void createHiddenDialog() {
        hiddenDialog = new JDialog();
        hiddenDialog.setSize(10, 10);
        
        // add the window focus listener to the hidden dialog
        hiddenDialog.addWindowFocusListener(new WindowFocusListener()
        {
            @Override
            public void windowLostFocus(WindowEvent e) { hideDialog(); }
            @Override
            public void windowGainedFocus(WindowEvent e) {}
        });
    }
    
    /** Adds tray icon mouse click listeners. */
    private void addTrayIconListeners() {
        trayIcon.addMouseListener(new MouseListener()
        {
            private void showPopupMenu(MouseEvent me) {
//                if (me.isPopupTrigger()) {
                menu.setLocation(me.getX(), me.getY());
                // place the hidden dialog at the same location
                hiddenDialog.setLocation(me.getX(), me.getY());
                // now the popup menu's invoker is the hidden dialog
                menu.setInvoker(hiddenDialog);
                // show the hidden dialog to check for focus loss
                showDialog();
                menu.setVisible(true);
//                }
            }
            
            @Override
            public void mouseClicked(MouseEvent me) { showPopupMenu(me); }
            @Override
            public void mouseReleased(MouseEvent me) { showPopupMenu(me); }
            @Override
            public void mousePressed(MouseEvent me) {}
            @Override
            public void mouseEntered(MouseEvent me) {}
            @Override
            public void mouseExited(MouseEvent me) {}
        });
        
        trayIcon.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ae) {
                System.out.println("actionPerformed");
            }
        });
    }
    
    /** Hides the hidden dialog. */
    private void hideDialog() { hiddenDialog.setVisible(false); }
    
    /** Shows the hidden dialog. */
    private void showDialog() { hiddenDialog.setVisible(true); }
    
    
    /**************************************************************************
     *                                                                        *
     * Abstract Implementation                                                *
     *                                                                        *
     *************************************************************************/
    
    /** Simple Swing JMenuItem wrapper. */
    private static class SwingPopupMenuItem extends TrayIconPopupMenu.PopupMenuItem<JMenuItem> {
        private static final int ACTION_LISTENERS_TO_KEEP = 1;
        
        public SwingPopupMenuItem(String menuItemText, ActionListener hideDialog) {
            super(new JMenuItem(menuItemText));
            // ensure hidden dialog goes away after selection
            menuItem.addActionListener(hideDialog);
        }
        
        @Override
        public void setActionListener(ActionListener listener) {
            ActionListener[] listeners = menuItem.getActionListeners();
            // remove all action listeners except the initial one
            for (int i = listeners.length - 1; i > ACTION_LISTENERS_TO_KEEP; --i) {
                menuItem.removeActionListener(listeners[i]);
            }
            
            if (listener != null) { menuItem.addActionListener(listener); }
        }
        
        @Override
        public void setEnabled(boolean enabled) { menuItem.setEnabled(enabled); }
        
    } // class SwingPopupMenuItem
    
    
    @Override
    protected void addMenuItemToMenu(PopupMenuItem<JMenuItem> item) { getPopupMenu().add(item.getMenuItem()); }
    
    @Override
    protected void addSeparatorToMenu() { getPopupMenu().addSeparator(); }
    
    @Override
    protected PopupMenuItem<JMenuItem> createAbout(String text) {
        return new SwingPopupMenuItem(text, action -> hideDialog());
    }
    
    @Override
    protected PopupMenuItem<JMenuItem> createRunScraper(String text) {
        return new SwingPopupMenuItem(text, action -> hideDialog());
    }
    
    @Override
    protected PopupMenuItem<JMenuItem> createDashboard(String text) {
        return new SwingPopupMenuItem(text, action -> hideDialog());
    }
    
    @Override
    protected PopupMenuItem<JMenuItem> createSettings(String text) {
        return new SwingPopupMenuItem(text, action -> hideDialog());
    }
    
    @Override
    protected PopupMenuItem<JMenuItem> createLogs(String text) {
        return new SwingPopupMenuItem(text, action -> hideDialog());
    }
    
    @Override
    protected PopupMenuItem<JMenuItem> createQuit(String text) {
        return new SwingPopupMenuItem(text, action -> hideDialog());
    }
    
    
}
imilarity index 76%
ename from src/main/java/com/bookiescrape/app/sample/SystemTrayController.java
ename to src/main/java/com/bookiescrape/app/tray/SystemTrayController.java
ndex 82d3970..bc4ae5d 100644
++ b/src/main/java/com/bookiescrape/app/tray/SystemTrayController.java

64c263d146c071fa036cb3b00e1580d9e591f8eb

@github-actions github-actions bot added the todo Needs to be done label Jan 4, 2021
@jhenly jhenly added the todo-log TODO related to logging label Jan 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
todo Needs to be done todo-log TODO related to logging
Projects
None yet
Development

No branches or pull requests

1 participant