Good Morning-
I'm using the java.awt.SystemTray and TrayIcon classes from 1.6 to create a system tray that acts essentially as a temperature monitor. It's very little code. When I test it from Eclipse, it works great. When I double-click the .jar on my workstation, it works great. When I launch it with java -jar temp.jar, it works great. When I launch it with javaw -jar temp.jar, I get no tray icon, but javaw sits in memory doing something.
When my users launch it with a .vbs that calls java -jar temp.jar and hides the resulting terminal window, they get no tray icon. When they call java -jar temp.jar, they get the tray icon... and the console window. When they call javaw -jar temp.jar, they get no tray icon. Any of these practices yields a java process sitting in memory.
When my users double-click the .jar file, they're asked to chose what to open it with. If they chose Java's executable, it says it doesn't know what to do (it isn't called with -jar). Windows doesn't see their jar files as executables like on mine.
So I have two issues. The result is the system tray icon won't display on users' computers without a window to accompany it. Any idea why? Is it potentially a bug?
Some code:
public class SysTrayController {
// The actual icon that will be updated
private TrayIcon icon;
// The last-set temperature
private int temp;
// The box that may or may not appear
private AlertBox box;
// No Data received (yet?)
public final static int NO_DATA = 0;
// High temperature threshold. TODO: Make this user-configurable.
private final static int HIGH_TEMP = 80;
// ... you guess
private final static String DEFAULT_ICON = "icons/default.png";
/**
* Initiate everything. Grab the system tray, plop the icon in it, and
* get the icon all set up and ready to go with the default image.
*/
public SysTrayController() {
box = new AlertBox();
SystemTray tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource(DEFAULT_ICON));
PopupMenu popup = new PopupMenu();
MenuItem exit = new MenuItem("Exit");
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
popup.add(exit);
icon = new TrayIcon(image, "Temperature Monitor", popup);
// On double-click, display the alert box
icon.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() >= 2) {
box.setVisible(true);
}
}
});
try {
tray.add(icon);
} catch (AWTException e) {
System.out.println(e);
}
}
/**
* Set the temperature.
*
* Call setIcon() to set the icon to the right number, update the alert
* box, and if it's time to, display the alert box.
*/
public void setTemp(int temp) {
if (this.temp != temp) {
this.temp = temp;
setIcon(temp);
icon.setToolTip(temp + " degrees");
box.setAlertMessage("Temperature in the Server Room is at " + temp + " degrees!");
box.setIcon(icon.getImage());
if (temp > HIGH_TEMP) {
box.setVisible(true);
icon.displayMessage("Alert", "Temperature in the server room is at " + temp + " degrees!", TrayIcon.MessageType.WARNING);
} else if (temp != NO_DATA){
box.setVisible(false);
}
}
}
/**
* Figure out which icon to set the tray icon to, scale it down, and
* set it.
*/
public void setIcon(int number) {
Image image = null;
if (number == NO_DATA) {
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource(DEFAULT_ICON));
} else if (number >= 60 && number < 100 ) {
String iconString = "icons/temp";
iconString += number;
iconString += ".png";
try {
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource(iconString));
} catch (NullPointerException e) {
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource(DEFAULT_ICON));
}
}
image = image.getScaledInstance(16, 16, Image.SCALE_SMOOTH);
icon.setImage(image);
}
/**
* Give back the current temperature.
*/
public int getTemp() {
return temp;
}
}
The main() that calls it looks like this:
public static void main(String[] args) {
SysTrayController controller = new SysTrayController();
Thermometer temp = new Thermometer(HOSTNAME);
while (true) {
controller.setTemp(temp.getTemp());
try {
if (controller.getTemp() == SysTrayController.NO_DATA) {
Thread.sleep(1000);
} else {
Thread.sleep(SLEEPTIME);
}
} catch (Exception e) {
System.out.println(e);
}
}
}