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 if an exception occurred while loading the icon image #28

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

log if an exception occurred while loading the icon image #28

github-actions bot opened this issue Jan 3, 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 3, 2021

log if an exception occurred while loading the icon image

// TODO log if an exception occurred while loading the icon image

    
    
    /**************************************************************************
     *                                                                        *
     * Constructor(s)                                                         *
     *                                                                        *
     *************************************************************************/
    
    /**
     * Creates a system tray controller with the application's system tray icon
     * image set to the default system tray icon image.
     * 
     * @throws UnsupportedOperationException if the system tray is not supported
     */
    public SystemTrayController() throws UnsupportedOperationException {
        this(null);
    }
    
    /**
     * Creates a system tray controller and sets the application's system tray
     * icon image to the image loaded from the specified image url.
     * 
     * @param iconImageUrl - the url to load the tray icon's image from, or
     *        {@code null} if the default system tray icon image should be used
     * @throws UnsupportedOperationException if the system tray is not supported
     */
    public SystemTrayController(URL iconImageUrl) throws UnsupportedOperationException {
        // ensure awt toolkit is initialized.
        java.awt.Toolkit.getDefaultToolkit();
        
        // assign system tray or throw if not supported
        tray = getSystemTrayOrThrowIfNotSupported();
        
        // listen for app raised to foreground/moved to background events
        Desktop.getDesktop().addAppEventListener(new AppFocusListener());
        
        // load specified icon image or use the default toolkit icon image
        defIcon = loadIconImageOrUseDefault(iconImageUrl);
        // create tray icon and add it to the system tray
        initTrayIcon();
        addAppTrayIconToSystemTray();
    }
    
    
    /**************************************************************************
     *                                                                        *
     * Public API                                                             *
     *                                                                        *
     *************************************************************************/
    
    /**
     * Displays a system tray notification to the user.
     * @param caption - the notification caption
     * @param text - the notification detail text
     * @param type - the type of notification
     * @see MessageType
     */
    public void notifyUser(String caption, String text, MessageType type) {
        runLater(() -> trayIcon.displayMessage(caption, text, type));
    }
    
    /**
     * Shuts down the system tray if it's supported, otherwise calling this
     * method is a no-op.
     */
    public void shutdown() {
        if (trayIcon == null) { return; }
        
        System.out.println("SystemTrayController: closing");
        
        runLater(() -> {
            Platform.exit();
            tray.remove(trayIcon);
        });
    }
    
    /**
     * Specifies the system tray icon's tool-tip message.
     * @param tip - the icon's tool-tip message to display
     */
    public void setToolTip(String tip) {
        if (trayIcon == null) { return; }
        
        runLater(() -> trayIcon.setToolTip(tip));
    }
    
    /**
     * Sets a status string at the first position in the context menu.
     * <p>
     * This status string appears as a disabled menu entry.
     * @param status - the string to display at the first position in the
     *        context menu
     * @see SystemTray#setStatus(String)
     */
    public void setStatus(String status) {
        if (trayIcon == null) { return; }
        
        // javax.swing.SwingUtilities.invokeLater(() -> trayIcon.get().);
    }
    
    /**
     * Specifies the image to use for the system tray icon.
     * @param imageUrl - image to use for the system tray icon
     * @see SystemTray#setImage(URL)
     */
    public void setIconImage(URL imageUrl) {
        if (trayIcon == null) { return; }
        
        runLater(() -> {
            defIcon = loadIconImageOrUseDefault(imageUrl);
            trayIcon.setImage(defIcon);
        });
    }
    
    /**
     * Specifies the URL of the website to open in a browser when the 'About'
     * menu item is selected.
     * @param url - the website URL to open when the 'About' menu item is
     *        selected
     */
    public void setAboutBrowserUrl(String url) {
        runLater(() -> {
            try {
                aboutUri = URI.create(url);
            } catch (Exception e) {
                // TODO log create URI exception rather than printing stack trace
                e.printStackTrace();
            }
        });
    }
    
    /**
     * Specifies the enabled state of the 'Run Scraper' menu item.
     * @param enabled - the enabled state of the 'Run Scraper' menu item
     */
    public void setRunScraperEnabled(boolean enabled) {
        runLater(() -> runScraper.setEnabled(enabled));
    }
    
    /**
     * Sets the about tray icon menu item selected action listener.
     * @param listener - the about selected listener
     */
    public void setOnAboutSelected(ActionListener listener) {
        setMenuItemActionListener(about, listener);
    }
    
    /**
     * Sets the run scraper tray icon menu item selected action listener.
     * @param listener - the run scraper selected listener
     */
    public void setOnRunScraperSelected(ActionListener listener) {
        setMenuItemActionListener(runScraper, listener);
    }
    
    /**
     * Sets the dashboard tray icon menu item selected action listener.
     * @param listener - the dashboard selected listener
     */
    public void setOnDashboardSelected(ActionListener listener) {
        setMenuItemActionListener(dashboard, listener);
    }
    
    /**
     * Sets the settings tray icon menu item selected action listener.
     * @param listener - the settings selected listener
     */
    public void setOnSettingsSelected(ActionListener listener) {
        setMenuItemActionListener(settings, listener);
    }
    
    /**
     * Sets the view logs tray icon menu item selected action listener.
     * @param listener - the view logs selected listener
     */
    public void setOnViewLogsSelected(ActionListener listener) {
        setMenuItemActionListener(logs, listener);
    }
    
    /**
     * Sets the quit tray icon menu item selected action listener.
     * <p>
     * The quit tray icon menu item has a preset action listener that handles
     * exiting of the application, therefore changing the action listener
     * should rarely, if ever, be needed.
     * @param listener - the quit selected listener
     */
    public void setOnQuitSelected(ActionListener listener) {
        setMenuItemActionListener(quit, listener);
    }
    
    
    /**************************************************************************
     *                                                                        *
     * Private API                                                            *
     *                                                                        *
     *************************************************************************/
    
    /** Gets the system tray or throws an UnsupportedOperationException if the
     *  system tray is not supported.
     */
    private SystemTray getSystemTrayOrThrowIfNotSupported() {
        UnsupportedOperationException uoe = new UnsupportedOperationException("system tray not supported.");
        
        if (!SystemTray.isSupported()) { throw uoe; }
        
        SystemTray tmp = null;
        try {
            tmp = SystemTray.getSystemTray();
        } catch (Exception e) {
            throw uoe;
        }
        
        return tmp;
    }
    
    /** Initializes the tray icon. */
    private void initTrayIcon() {
        trayIcon = new TrayIcon(defIcon, Main.APP_NAME);
        
        // allow the system to auto-size the tray icon
        trayIcon.setImageAutoSize(true);
        // set the tray icon's tool-tip
        // trayIcon.get().setToolTip("");
        
        // add notification click listener to tray icon
        trayIcon.setActionCommand("notification-clicked");
        trayIcon.addActionListener(this::onNotificationClicked);
        
        // create and set tray icon's popup menu
        trayIcon.setPopupMenu(createPopupMenu());
    }
    
    /**
     *  Helper that loads the specified icon image url or uses the default
     *  toolkit icon image.
     */
    private Image loadIconImageOrUseDefault(URL iconImageUrl) {
        Image icon = null;
        
        if (iconImageUrl != null) {
            try {
                icon = Toolkit.getDefaultToolkit().createImage(iconImageUrl);
            } catch (Exception e) {
                // TODO log if an exception occurred while loading the icon image
                icon = Taskbar.getTaskbar().getIconImage();
            }
        } else {
            icon = Taskbar.getTaskbar().getIconImage();
        }
        
        return icon;
    }
    
    /** Adds application tray icon to system tray. */
    private void addAppTrayIconToSystemTray() {
        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            // TODO log tray add exception rather than printing stack trace
            e.printStackTrace();
        }
        
    }
    
    /**
     * Handles clicking actions on notifications.
     * @param action - the clicking action to handle
     */
    private void onNotificationClicked(ActionEvent action) {
        System.out.println(action.getActionCommand());
        System.out.println("Notification Clicked");
    }
    
    /** Listeners for app raised to foreground/moved to background events. */
    private class AppFocusListener implements AppForegroundListener {
        
        @Override
        public void appRaisedToForeground(AppForegroundEvent e) {
            System.out.println("SystemTrayController: app moved to foreground");
        }
        
        @Override
        public void appMovedToBackground(AppForegroundEvent e) {
            System.out.println("SystemTrayController: app moved to background");
        }
        
    } // class AppFocusListener
    
    /** Convenience helper that invokes {@code SwingUtils.invokeLater(toRun)}. */
    private void runLater(final Runnable toRun) {
        javax.swing.SwingUtilities.invokeLater(toRun);
    }
    
    /** Helper method used by setOn*Selected methods. */
    private void setMenuItemActionListener(MenuItem menuItem, ActionListener listener) {
        runLater(() -> {
            // remove any action listeners from menu item
            for (ActionListener al : menuItem.getActionListeners()) { menuItem.removeActionListener(al); }
            // add specified action listener to menu item
            menuItem.addActionListener(listener);
        });
    }
    
    
    /**************************************************************************
     *                                                                        *
     * Popup Menu Creation                                                    *
     *                                                                        *
     *************************************************************************/
    
    /** Creates the menu items and lays out the tray icon's popup menu. */
    private PopupMenu createPopupMenu() {
        // init the menu items before adding them to the menu
        initMenuItems();
        
        PopupMenu menu = new PopupMenu();
        
        menu.add(about);
        menu.add(runScraper);
        menu.addSeparator();
        menu.add(dashboard);
        menu.add(settings);
        menu.add(logs);
        menu.addSeparator();
        menu.add(quit);
        
        return menu;
    }
    
    /** Initializes the popup menu's items. */
    private void initMenuItems() {
        runScraper = new MenuItem("Run Scraper");
        dashboard = new MenuItem("Dashboard");
        settings = new MenuItem("Settings");
        logs = new MenuItem("View Logs");
        
        // about and quit have default action listeners
        initAboutMenuItem();
        initQuitMenuItem();
    }
    
    /**
     * Creates about menu item and sets its action listener to open a browser
     * to the application's website.
     */
    private void initAboutMenuItem() {
        about = new MenuItem("About");
        about.addActionListener(e -> {
            System.out.println("About was selected");
            
            try {
                Desktop.getDesktop().browse(aboutUri);
            } catch (IOException e1) {
                // TODO log browser exception rather than print stack trace
                e1.printStackTrace();
            }
        });
    }
    
    /**
     * Creates quit menu item and sets its action listener to handle exiting of
     * the application and removal of the system tray icon.
     */
    private void initQuitMenuItem() {
        quit = new MenuItem("Quit Bookie Scrape");
        quit.addActionListener(e -> {
            System.out.println("Quit was selected");
            
            Platform.exit();
            tray.remove(trayIcon);
        });
    }
    
    
} // class SystemTrayController

a7cdb147233f71a8e1c3bfeafd55d5cc5685791d

@github-actions github-actions bot added the todo Needs to be done label Jan 3, 2021
@jhenly jhenly added the todo-log TODO related to logging label Jan 3, 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