2013-02-27 74 views
-4

我实例化一个Java托盘图标,并希望显示在它displayMessage用下面的代码:Java的托盘图标NPE

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

但不是消息,我得到一个NullPointerException,我现在为什么不?

这NPE:

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

在第65行我实例的类的构造函数,并在155我打电话给该对象。

谢谢你的帮忙!

编辑 - 守则:

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); 
} 

}

+1

你如何实例化trayIcon? – BobTheBuilder 2013-02-27 10:54:08

+0

“*在第65行中,我通过构造函数实例化了实例,在155中我调用了这个对象。*”,哪个/哪个类?显示你的代码。 – 2013-02-27 10:54:40

+0

得到了一些示例代码 – MadProgrammer 2013-02-27 10:54:41

回答

2

您的静态trayIconnull。您在Tray的构造函数中创建了一个新的第二个trayIcon,但是您的showMsg -Method使用静态trayIcon而不是本地构造函数。

Tray -constructor第一行中删除:

final TrayIcon trayIcon; 

,现在你初始化静态参考。

1

TrayIcon.displayMessage抛出一个NullPointerException如果两个captiontextnull

captiontext是该方法的前两个参数。

所以,这是你应该在你的代码进行检查:

  • trayIcon应该在方法调用之前被实例化
  • _titel_msg不应该在同一时间
3
null

问题是你正在构造函数中重新定义相同的trayIcon变量。

final TrayIcon trayIcon; 

所以,当你通过调用trayIcon = new TrayIcon(image, Main.programmName, popup);方法的局部变量初始化变量初始化,而不是全球性的。所以当你在全局变量上调用displayMessage时,你得到了NPE。

解决方法是从构造函数中删除该行。 OTOH你应该在showMessage方法中使用null检查,因为如果你的条件(SystemTray.isSupported())置为false,你的trayIcon变量仍然可以为null。总是放一个空检查更好。

的另一个好处通过MadProgrammer在评论说:

在这种情况下,利用静态变量,可能不是一个好主意。因为开发者有可能能够实例化多个实例,并且这种情况下最终会导致错误的引用。相反,尝试使Tray类成为单例或从变量声明中删除静态关键字。