Question

I instanced a Java trayIcon and want to show a displayMessage on it with the following code:

trayIcon.displayMessage(_titel, _msg, TrayIcon.MessageType.INFO);

But instead of the Message, I get a NullpointerException and I don't now why?

This NPE:

Exception in thread "main" java.lang.NullPointerException
    at myPckg.Tray.showMsg(Tray.java:165)
    at myPckg.Main.main(Main.java:65)

In line 65 I instance the Class by Constructor, and in 155 I'm calling this object.

Thank you for helping!

Edit- The Code:

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;

public class Tray {
//http://www.oracle.com/technetwork/articles/javase/index-136970.html   

public static MenuItem itmSpeicher = new MenuItem("0% von 0MB belegt");
public static MenuItem itmSyncStatus = new MenuItem("Synchronisation starten");
public static PopupMenu popup = new PopupMenu();
public static TrayIcon trayIcon = null;
public Tray(){
final TrayIcon trayIcon;


if (SystemTray.isSupported()) {

    SystemTray tray = SystemTray.getSystemTray();

    Image image = null;
    try {
        image = ImageIO.read(getClass().getResource("sync.gif"));
    } catch (IOException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
        new Thread(){ public void run(){ Main.syncProzess.reset();}}.start();
    }

    MouseListener mouseListener = new MouseListener() {

        public void mouseClicked(MouseEvent e) {
              Main.MainWindow.setVisible(true);
        }

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }


    };

    ActionListener exitListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            int x = JOptionPane.showConfirmDialog(null, "Synchronisation wirklich beenden?");
            if(x==0){
                System.out.println("Beende... "+x);
                System.exit(0);
            }
        }
    };

    ActionListener itmSyncStatusListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Main.syncProzess.starte();
        }
    };
    ActionListener itmFolderListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                Runtime.getRuntime().exec("explorer.exe "+ Main.syncDir );
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                new Thread(){ public void run(){ Main.syncProzess.reset();}}.start();
            }

        }
    };
    ActionListener itmSettingListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Main.MainWindow.setVisible(true);
        }
    };


    MenuItem defaultItem = new MenuItem("Programm beenden");
    defaultItem.addActionListener(exitListener);

    itmSyncStatus.addActionListener(itmSyncStatusListener);

    MenuItem itmFolder = new MenuItem(Main.programmName + " Ordner öffnen");
    itmFolder.addActionListener(itmFolderListener);

    MenuItem itmSettings = new MenuItem("Einstellungen");
    itmFolder.addActionListener(itmSettingListener);

    popup.add(itmFolder);
    popup.add(itmSpeicher);
    popup.add(itmSettings);
    popup.add(itmSyncStatus);
    popup.add(defaultItem);


    trayIcon = new TrayIcon(image, Main.programmName, popup);

    ActionListener doubleClick = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                Runtime.getRuntime().exec("explorer.exe "+ Main.syncDir );
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                new Thread(){ public void run(){ Main.syncProzess.reset();}}.start();
            }
        }
    };


    trayIcon.setImageAutoSize(true);
    trayIcon.addActionListener(doubleClick);
    trayIcon.addMouseListener(mouseListener);

    try {
        tray.add(trayIcon);
    } catch (AWTException e) {
        System.err.println("TrayIcon konnte nicht erstellt werden!");
        new Thread(){ public void run(){ Main.syncProzess.reset();}}.start();
    }
    showMsg("Hello", "It's working");

} else {
    //Not supportet
}


}

public void showMsg(String _titel, String _msg){
    trayIcon.displayMessage(_titel, _msg, TrayIcon.MessageType.INFO);
}

}

Was it helpful?

Solution 2

Your static trayIcon is null. You create in the constructor of Tray a new, second trayIcon, but your showMsg-Method uses the static trayIcon not the constructor local.

Remove in your Tray-constructor the first line:

final TrayIcon trayIcon;

and now you initialize the static reference.

OTHER TIPS

The problem is you are re-defining the same trayIcon variable in constructor.

final TrayIcon trayIcon;

So when you initiate the variable by calling trayIcon = new TrayIcon(image, Main.programmName, popup); the local variable of the method is initialized and not the global one. So when you call displayMessage on global variable you got NPE.

Solution would be to just remove the line from constructor. OTOH you should put null check in showMessage method, as your trayIcon variable can still be null if your condition (SystemTray.isSupported()) stands false. It's better to always put a null check.

Another good thing said by MadProgrammer in comment:

The use of static variables in this case is probably not a good idea. Because it's possible for a developer to capable of instantiating more then one instance, and that case you would end up with erroneous references all over the place. Instead, try and make the Tray class a singleton or remove static keyword from the variable declaration.

TrayIcon.displayMessage throws a NullPointerException if both caption and text are null.

caption and text are the first two parameters of the method, in that order.

So, this is what you should be checking in your code:

  • trayIcon should be instantiated before the method call
  • _titel and _msg should not be null at the same time
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top