I am not a programmer by trade (any Java knowledge I have comes from the School of Hard Knocks). Please forgive me for the stupid question I'm about to ask, and answer appropriately.
A Java app I'm working on uses very buggy platform-agnostic notifications (such as when a file has been successfully downloaded). I want to use platform-aware notifications. The code to raise a notification on Linux is quite simple:
import org.gnome.gtk.Gtk;
import org.gnome.notify.Notify;
import org.gnome.notify.Notification;
public class HelloWorld
{
public static void main(String[] args) {
Gtk.init(args);
Notify.init("Hello world");
Notification Hello = new Notification("Hello world!", "This is an example notification.", "dialog-information");
Hello.show();
}
}
On Mac it's a bit more complicated but still doable:
interface NsUserNotificationsBridge extends Library {
NsUserNotificationsBridge instance = (NsUserNotificationsBridge)
Native.loadLibrary("/usr/local/lib/NsUserNotificationsBridge.dylib", NsUserNotificationsBridge.class);
public int sendNotification(String title, String subtitle, String text, int timeoffset);
}
It requires a dylib obtainable from this github repository: https://github.com/petesh/OSxNotificationCenter
Windows way is like this:
import java.awt.*;
import java.awt.TrayIcon.MessageType;
public class TrayIconDemo {
public static void main(String[] args) throws AWTException {
if (SystemTray.isSupported()) {
TrayIconDemo td = new TrayIconDemo();
td.displayTray();
} else {
System.err.println("System tray not supported!");
}
}
public void displayTray() throws AWTException {
//Obtain only one instance of the SystemTray object
SystemTray tray = SystemTray.getSystemTray();
//If the icon is a file
Image image = Toolkit.getDefaultToolkit().createImage("icon.png");
//Alternative (if the icon is on the classpath):
//Image image = Toolkit.getDefaultToolkit().createImage(getClass().getResource("icon.png"));
TrayIcon trayIcon = new TrayIcon(image, "Tray Demo");
//Let the system resize the image if needed
trayIcon.setImageAutoSize(true);
//Set tooltip text for the tray icon
trayIcon.setToolTip("System tray icon demo");
tray.add(trayIcon);
trayIcon.displayMessage("Hello, World", "notification demo", MessageType.INFO);
}
}
The point is, I want these snippets to execute only on the appropriate platform; I don't want Java to compile, say, the GTK method on Windows, because the dependency for it doesn't exist.
How do I make it so that Java recognises it, like "Hey, I'm compiling for a Mac system, so I'm using the Mac version of the code."
In the interest of having something simple and clean with no additional dependencies, I would forego all the native libraries, and instead rely on native programs that I’m pretty sure are guaranteed (or at least likely) to be available on each respective system:
String title = "Hello world!";
String message = "This is an example notification.";
Image image = ImageIO.read(getClass().getResource("icon.png"));
String os = System.getProperty("os.name");
if (os.contains("Linux")) {
ProcessBuilder builder = new ProcessBuilder(
"zenity",
"--notification",
"--text=" + title + "\\n" + message);
builder.inheritIO().start();
} else if (os.contains("Mac")) {
ProcessBuilder builder = new ProcessBuilder(
"osascript", "-e",
"display notification \"" + message + "\""
+ " with title \"" + title + "\"");
builder.inheritIO().start();
} else if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
TrayIcon trayIcon = new TrayIcon(image, "Tray Demo");
trayIcon.setImageAutoSize(true);
tray.add(trayIcon);
trayIcon.displayMessage(title, message, TrayIcon.MessageType.INFO);
}