SystemTray/src/dorkbox/systemTray/swing/_SwingTray.java

144 lines
4.6 KiB
Java
Raw Normal View History

2014-11-24 17:40:06 +01:00
/*
* Copyright 2014 dorkbox, llc
*
* 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 dorkbox.systemTray.swing;
2014-11-03 02:11:03 +01:00
import java.awt.AWTException;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.TrayIcon;
2014-11-03 02:11:03 +01:00
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
2014-11-03 02:11:03 +01:00
2016-09-22 15:21:22 +02:00
import javax.swing.ImageIcon;
2016-10-03 20:13:00 +02:00
import javax.swing.JPopupMenu;
2016-09-22 15:21:22 +02:00
2016-10-10 00:26:52 +02:00
import dorkbox.systemTray.Entry;
2016-09-22 15:21:22 +02:00
2014-11-03 02:11:03 +01:00
/**
2016-09-22 15:21:22 +02:00
* Class for handling all system tray interaction, via SWING.
*
* It doesn't work well on linux. See bugs:
* http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6267936
* http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
* https://stackoverflow.com/questions/331407/java-trayicon-using-image-with-transparent-background/3882028#3882028
2014-11-03 02:11:03 +01:00
*/
@SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter", "WeakerAccess"})
public
2016-10-10 00:26:52 +02:00
class _SwingTray extends _Tray {
private volatile SystemTray tray;
private volatile TrayIcon trayIcon;
// is the system tray visible or not.
private volatile boolean visible = true;
2014-11-24 17:40:06 +01:00
// Called in the EDT
public
_SwingTray(final dorkbox.systemTray.SystemTray systemTray) {
super(systemTray, null, new TrayPopup());
_SwingTray.this.tray = SystemTray.getSystemTray();
2014-11-03 02:11:03 +01:00
}
public
void shutdown() {
2016-10-04 00:21:40 +02:00
dispatchAndWait(new Runnable() {
@Override
public
void run() {
2016-09-28 17:20:13 +02:00
tray.remove(trayIcon);
2016-09-28 17:20:13 +02:00
synchronized (menuEntries) {
2016-10-10 00:26:52 +02:00
for (Entry entry : menuEntries) {
entry.remove();
}
2016-09-28 17:20:13 +02:00
menuEntries.clear();
}
remove();
}
});
2014-11-24 17:40:06 +01:00
}
2014-11-03 02:11:03 +01:00
public
void setImage_(final File iconFile) {
dispatch(new Runnable() {
2014-11-24 17:40:06 +01:00
@Override
public
void run() {
// stupid java won't scale it right away, so we have to do this twice to get the correct size
final Image trayImage = new ImageIcon(iconFile.getAbsolutePath()).getImage();
trayImage.flush();
2016-09-29 03:00:29 +02:00
if (trayIcon == null) {
2016-09-28 17:20:13 +02:00
// here we init. everything
trayIcon = new TrayIcon(trayImage);
JPopupMenu popupMenu = (JPopupMenu) _native;
popupMenu.pack();
popupMenu.setFocusable(true);
2016-10-10 00:26:52 +02:00
// appindicators DO NOT support anything other than PLAIN gtk-menus (which we hack to support swing menus)
2016-09-28 17:20:13 +02:00
// they ALSO do not support tooltips, so we cater to the lowest common denominator
2016-10-10 00:26:52 +02:00
// trayIcon.setToolTip("app name");
2016-09-28 17:20:13 +02:00
trayIcon.addMouseListener(new MouseAdapter() {
@Override
public
void mousePressed(MouseEvent e) {
TrayPopup popupMenu = (TrayPopup) _native;
popupMenu.doShow(e.getPoint(), 0);
}
2016-09-28 17:20:13 +02:00
});
try {
2016-09-29 03:00:29 +02:00
tray.add(trayIcon);
2016-09-28 17:20:13 +02:00
} catch (AWTException e) {
dorkbox.systemTray.SystemTray.logger.error("TrayIcon could not be added.", e);
}
2016-09-28 17:20:13 +02:00
} else {
trayIcon.setImage(trayImage);
}
2016-10-09 20:20:23 +02:00
((TrayPopup) _native).setTitleBarImage(iconFile);
2014-11-24 17:40:06 +01:00
}
});
2014-11-03 02:11:03 +01:00
}
public
void setEnabled(final boolean setEnabled) {
visible = !setEnabled;
dispatch(new Runnable() {
@Override
public
void run() {
if (visible && !setEnabled) {
tray.remove(trayIcon);
}
else if (!visible && setEnabled) {
try {
tray.add(trayIcon);
} catch (AWTException e) {
dorkbox.systemTray.SystemTray.logger.error("Error adding the icon back to the tray");
}
}
}
});
}
2014-11-03 02:11:03 +01:00
}