2013-02-27 88 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類成爲單例或從變量聲明中刪除靜態關鍵字。