views:

586

answers:

5

Our customer is using our software (Java Swing application started using Webstart) besides other software like MS Office, to do his job. From time to time there are important events he has to deal with in our software without much delay. The customer wants to have a prominent notification then. Now he might be using Excel at the moment, so popping up a message box will not suffice (although the entry in the task bar will be flashing).

We need some mechanism like the Outlook notifier, i.e. a popup that is always visible but does not steal the focus. The notifier should be displayed all the time until the reason for the message has gone (the user has solved the issue) or the user has closed the message (like in outlook). Additionally we want to display a tray icon and maybe play a sound.

I've tried the Java6 java.awt.SystemTray as well as the JDIC (version 0.9 since we already have that lib in the classpath of that project) equivalent, but I did not find a way to set the timeout of the TrayIcon.displayMessage method, and the message seems not to be always on top.

Is there any other option besides JNI to achieve the requested behavior?

If JNI is the only choice and since Windows is the only platform of our customers, is the Outlook notifier an Outlook only feature, or is it freely usable through the Windows API?

Or what other options exist to notify the user about an important task to perform in one software without hindering him to complete his current task in another software. A system modal dialog therefore is no option!

+2  A: 

With OS X the obvious answer would be to use Growl. But there exists a little project doing a similar service on windows environments. It's called Snarl. This might give you a new option to try.

Drawback: You'll have to install a tool on the client's machines. From your description I assume you have a defined group of users on company workplaces, right? So this might acceptable, nevertheless.

mkoeller
Yes, it is a defined group of users on company workplaces, I will have a look at the tool.
Tobias Schulte
Growl and Snarl seem to be impressive tools and seem to be easily used from an application without much effort with a nice result. However the need to install the tool on every client pc might be a no go for our customer.
Tobias Schulte
Snarl4Java is published under GPL and therefore no option for us. The only way would be to implement the connection using JNI ourself.
Tobias Schulte
+1  A: 

Using Tray: Which component are you using to show message (JPopup, JDialog, JFrame, JWindow)?

Whichever you use, try to make it unfocusable(override isFocusable method) and call toFront.

Also let me know the result.

java.awt.TrayIcon has a method displayMessage that pops up a bubble with an icon depending on the messagetype, a title and a text. So there is no control of how the message is displayed. This feature is documented to be platform dependent. Therefore the actual behavior might change in the future.
Tobias Schulte
A: 

If you've got a budget, consider a license for JIDE. JIDE has an alert popup designed to look exactly like the outlook popup/alert widget.

basszero
+2  A: 

Try using setAlwaysOnTop on your JFrame/JWindow.

McDowell
Nice hint. Using an undecoraded JDialog with setAlwaysOnTop does not steel the focus and really is always on top system-wide. In combination with the java.awt.SystemTray this might be what we need.
Tobias Schulte
I think this will be the way to go for us, since Snarl is nice but not really an option because of the install overhead. Using java.awt.GraphicsEnvironment I will try to position the window at the lower left corner (assuming the user has the task bar at the default location).
Tobias Schulte
A: 

Here is an example:

class AlertWindow extends Window implements MouseListener
{
    AlertWindow(JFrame frame)
    {
        super(frame);
        this.setAlwaysOnTop(true);
        this.setFocusable(false);
        this.setSize(200, 200);
        this.setLocation(500, 0);
        this.setBackground(Color.BLACK);
        addMouseListener(this);

        try {
            Class<?> awtUtilitiesClass = Class.forName("com.sun.awt.AWTUtilities");
            Method mSetWindowOpacity = awtUtilitiesClass.getMethod("setWindowOpacity", Window.class, float.class);
            mSetWindowOpacity.invoke(null, this, Float.valueOf(0.50f));
        } catch (NoSuchMethodException ex) {
            ex.printStackTrace();
        } catch (SecurityException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
    }

    public void mouseClicked(MouseEvent e)
    {
        this.setVisible(false);
    }

    public void mousePressed(MouseEvent e)
    {
    }

    public void mouseReleased(MouseEvent e)
    {
    }

    public void mouseEntered(MouseEvent e)
    {
    }

    public void mouseExited(MouseEvent e)
    {
    }
}
l_39217_l
Since you do the same thing with all of the exceptions... why not just cath Exception instead? Or am I missing something?
SeanJA