2013-02-27 2 views
-4

Я инстанс на Java TrayIcon и хочу, чтобы показать displayMessage на него со следующим кодом:Java Tray Icon 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, я звоню этот объект.

Благодарим за помощь!

Edit- Кодекс:

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

Как вы создаете лоток? – BobTheBuilder

+0

"* В строке 65 Я экземпляр класса по конструктору, и в 155 я вызываю этот объект. *", Из какого/какого класса? Покажите свой код. –

+0

Получил код примера – MadProgrammer

ответ

2

Ваш статический trayIcon: null. Вы создаете в конструкторе Tray новый, второй trayIcon, но ваш showMsg -Method использует статический trayIcon не конструктор локальный.

Снимать в вашем Tray -constructor первой линии:

final TrayIcon trayIcon; 

и теперь вы инициализировать статическую ссылку.

1

TrayIcon.displayMessage бросает NullPointerException, если оба caption и text являются null.

caption и text - первые два параметра метода в указанном порядке.

Итак, это то, что вы должны проверять в своем коде:

  • trayIcon должно быть реализованным до вызова метода
  • _titel и _msg не должны быть null одновременно
3

Проблема в том, что вы переопределяете одну и ту же переменную trayIcon в конструкторе.

final TrayIcon trayIcon; 

Итак, когда вы начинаете переменную, вызвав trayIcon = new TrayIcon(image, Main.programmName, popup); локальная переменная метода инициализации, а не глобальный. Поэтому, когда вы вызываете displayMessage для глобальной переменной, вы получаете NPE.

Решение состоит в том, чтобы просто удалить строку из конструктора. OTOH вы должны поместить нулевую проверку в метод showMessage, так как ваша переменная trayIcon может по-прежнему иметь значение null, если ваше условие (SystemTray.isSupported()) стоит false. Лучше всегда ставить нулевую проверку.

Другая хорошая вещь сказано MadProgrammer в комментарии:

Использование статических переменных в этом случае, вероятно, не является хорошей идеей. Поскольку разработчик может создать экземпляр более одного экземпляра, и в этом случае вы получите ошибочные ссылки повсюду. Вместо этого попробуйте сделать класс Tray одиночным или удалить статическое ключевое слово из объявления переменной.