diff --git a/src/main/java/com/jagrosh/jmusicbot/gui/GUI.java b/src/main/java/com/jagrosh/jmusicbot/gui/GUI.java index e3f47ae7a..3a82a07fb 100644 --- a/src/main/java/com/jagrosh/jmusicbot/gui/GUI.java +++ b/src/main/java/com/jagrosh/jmusicbot/gui/GUI.java @@ -15,11 +15,10 @@ */ package com.jagrosh.jmusicbot.gui; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import javax.swing.JFrame; -import javax.swing.JTabbedPane; -import javax.swing.WindowConstants; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + import com.jagrosh.jmusicbot.Bot; @@ -27,41 +26,37 @@ * * @author John Grosh */ -public class GUI extends JFrame +public class GUI extends JFrame { private final ConsolePanel console; private final Bot bot; - - public GUI(Bot bot) + private final OptionsPanel optionsPanel; + + public GUI(Bot bot) { super(); this.bot = bot; console = new ConsolePanel(); + optionsPanel = new OptionsPanel(); } - + public void init() { setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setTitle("JMusicBot"); JTabbedPane tabs = new JTabbedPane(); tabs.add("Console", console); + tabs.add("Options", optionsPanel); getContentPane().add(tabs); pack(); setLocationRelativeTo(null); setVisible(true); - addWindowListener(new WindowListener() + addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent e) { /* unused */ } - @Override public void windowClosing(WindowEvent e) + @Override public void windowClosing(WindowEvent e) { - try - { - bot.shutdown(); - } - catch(Exception ex) - { - System.exit(0); - } + shutdown(); } @Override public void windowClosed(WindowEvent e) { /* unused */ } @Override public void windowIconified(WindowEvent e) { /* unused */ } @@ -69,5 +64,74 @@ public void init() @Override public void windowActivated(WindowEvent e) { /* unused */ } @Override public void windowDeactivated(WindowEvent e) { /* unused */ } }); + + if (SystemTray.isSupported()) + { + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + setupMinimizeToTray(); + } + } + + private void setupMinimizeToTray() + { + Image icon = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/icon16.png")); + MenuItem exit = new MenuItem("Exit"); + exit.addActionListener(e -> shutdown()); + + MenuItem nameLabel = new MenuItem("JMusicBot"); + nameLabel.setEnabled(false); + + PopupMenu menu = new PopupMenu(); + menu.add(nameLabel); + menu.addSeparator(); + menu.add(exit); + + SystemTray tray = SystemTray.getSystemTray(); + TrayIcon trayIcon = new TrayIcon(icon, "JMusicBot", menu); + + // Restore the window when the user clicks the tray icon + trayIcon.addMouseListener(new MouseAdapter() + { + @Override public void mouseClicked(MouseEvent e) + { + if (e.getButton() != MouseEvent.BUTTON1) + { + return; + } + + setVisible(true); + setExtendedState(JFrame.NORMAL); + tray.remove(trayIcon); + } + }); + + // Minimize the window to the system tray when the user clicks the minimize button + // and the option "minimize to tray" is active + addWindowStateListener(e -> { + if (e.getNewState() == JFrame.ICONIFIED && optionsPanel.isMinimizeToTraySelected()) + { + try + { + setVisible(false); + tray.add(trayIcon); + } + catch (AWTException ex) + { + System.err.println("TrayIcon could not be added."); + } + } + }); + } + + private void shutdown() + { + try + { + bot.shutdown(); + } + catch(Exception ex) + { + System.exit(0); + } } } diff --git a/src/main/java/com/jagrosh/jmusicbot/gui/OptionsPanel.java b/src/main/java/com/jagrosh/jmusicbot/gui/OptionsPanel.java new file mode 100644 index 000000000..3734f8d24 --- /dev/null +++ b/src/main/java/com/jagrosh/jmusicbot/gui/OptionsPanel.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016 John Grosh . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jagrosh.jmusicbot.gui; + +import javax.swing.*; +import java.util.prefs.Preferences; + +/** + * @author Wolfgang Schwendtbauer + */ +public class OptionsPanel extends JPanel +{ + private static final String KEY_MINIMIZE_TO_SYSTEM_TRAY = "minimizeToSystemTray"; + + private final Preferences prefs; + private final JCheckBox minimizeToTrayCheckbox; + + public OptionsPanel() + { + prefs = Preferences.userNodeForPackage(getClass()); + + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + minimizeToTrayCheckbox = new JCheckBox("Minimize to system tray"); + add(minimizeToTrayCheckbox); + + loadPreferences(); + addListeners(); + } + + private void loadPreferences() + { + minimizeToTrayCheckbox.setSelected(prefs.getBoolean(KEY_MINIMIZE_TO_SYSTEM_TRAY, false)); + } + + private void addListeners() + { + minimizeToTrayCheckbox.addActionListener(e -> prefs.putBoolean(KEY_MINIMIZE_TO_SYSTEM_TRAY, minimizeToTrayCheckbox.isSelected())); + } + + public boolean isMinimizeToTraySelected() + { + return minimizeToTrayCheckbox.isSelected(); + } +} diff --git a/src/main/resources/icon16.png b/src/main/resources/icon16.png new file mode 100644 index 000000000..1003990c2 Binary files /dev/null and b/src/main/resources/icon16.png differ