-4

JavaのtrayIconをインスタンス化し、次のコードでdisplayMessageを表示したいと思います。

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

}

4

3 に答える 3

3

問題は、コンストラクターで同じtrayIcon変数を再定義していることです。

final TrayIcon trayIcon;

trayIcon = new TrayIcon(image, Main.programmName, popup);したがって、メソッドのローカル変数を呼び出して変数を開始すると、グローバル変数ではなく初期化されます。したがって、グローバル変数でdisplayMessageを呼び出すと、NPEが取得されます。

解決策は、コンストラクターから行を削除することです。(SystemTray.isSupported())OTOH条件がfalseの場合、trayIcon変数はnullになる可能性があるため、showMessageメソッドにnullチェックを入れる必要があります。常にnullチェックを入れることをお勧めします。

MadProgrammerがコメントで言ったもう1つの良いこと:

この場合の静的変数の使用は、おそらく良い考えではありません。開発者が複数のインスタンスをインスタンス化できる可能性があるため、その場合、至る所で誤った参照が発生することになります。代わりに、Trayクラスをシングルトンにするか、変数宣言から静的キーワードを削除してみてください。

于 2013-02-27T11:08:19.483 に答える
2

あなたの静的trayIconnullです。Traynew、secondのコンストラクターで作成しtrayIconますが、showMsg-MethodはtrayIconコンストラクターlocalではなくstaticを使用します。

Tray-コンストラクターの最初の行を削除します。

final TrayIcon trayIcon;

次に、静的参照を初期化します。

于 2013-02-27T11:10:15.837 に答える
1

TrayIcon.displayMessageとがNullPointerException両方の場合はaをスローします。captiontextnull

captionおよびtextは、メソッドの最初の2つのパラメーターです。

したがって、これはコードでチェックする必要があるものです。

  • trayIconメソッド呼び出しの前にインスタンス化する必要があります
  • _titel同時にしては_msgいけませんnull
于 2013-02-27T11:00:29.627 に答える