javafx NullPointerException con controlesfx Notificaciones componnets
Quiero desarrollar una aplicación que utilice controlesfx Notificaciones para mostrar algunas notificaciones en el modo de bandeja del sistema. En modo normal, mi aplicación funciona bien y la notificación se puede mostrar con éxito. Pero cuando oculto el escenario en la bandeja del sistema, se produce NullPointerException. No sé cómo puedo solucionar este problema.
import java.awt.AWTException;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionListener;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class TryIconNotification extends Application {
private boolean firstTime;
private TrayIcon trayIcon;
@Override
public void start(Stage stage) throws Exception {
firstTime = true;
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
createTrayIcon(stage);
firstTime = true;
Platform.setImplicitExit(false);
stage.setScene(scene);
stage.show();
}
public void createTrayIcon(final Stage stage) {
if (SystemTray.isSupported()) {
// get the SystemTray instance
SystemTray tray = SystemTray.getSystemTray();
// load an image
java.awt.Image image = null;
image = Toolkit.getDefaultToolkit().getImage("icons\\iconify.png");
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent t) {
hide(stage);
}
});
// create a action listener to listen for default action executed on the tray icon
final ActionListener closeListener = new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
stage.hide();
}
};
ActionListener showListener = new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
Platform.runLater(new Runnable() {
@Override
public void run() {
stage.show();
}
});
}
};
// create a popup menu
PopupMenu popup = new PopupMenu();
MenuItem showItem = new MenuItem("Open app");
showItem.addActionListener(showListener);
popup.add(showItem);
MenuItem closeItem = new MenuItem("Exit");
closeItem.addActionListener(closeListener);
popup.add(closeItem);
/// ... add other items
// construct a TrayIcon
trayIcon = new TrayIcon(image, "Systray", popup);
// set the TrayIcon properties
trayIcon.addActionListener(showListener);
// ...
// add the tray image
try {
tray.add(trayIcon);
} catch (AWTException e) {
System.err.println(e);
}
// ...
}
}
public void showProgramIsMinimizedMsg() {
//only in first time show the message
if (firstTime) {
trayIcon.displayMessage("System Tray",
"Iconified",
TrayIcon.MessageType.INFO);
firstTime = false;
}
}
private void hide(final Stage stage) {
Platform.runLater(new Runnable() {
@Override
public void run() {
if (SystemTray.isSupported()) {
stage.hide();
showProgramIsMinimizedMsg();
} else {
System.exit(0);
System.out.println("Not Support Sys Tray");
}
}
});
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Y esta es mi clase de controlador:
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import org.controlsfx.control.Notifications;
public class FXMLDocumentController implements Initializable {
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event) {
Stage stage = (Stage) label.getScene().getWindow();
stage.hide();
}
public void createNotification() {
Notifications.create()
.text("This is a Notification")
.title("Notifications")
.showInformation();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Platform.runLater(()->createNotification());
}
}, 5000, 10000);
}
}