JavaFX ControlsFX-Notification öffnet nicht wenn kein JavaFX-Fenster offen.

Toriath

Mitglied
Guten Morgen!
Ich bin Azubi zum FIAE und arbeite gerade an einem JavaFX-Projekt und bin auf ein kleines Problem gestoßen!

Vorraussetzungen:
  • Javaversion: 8, JavaFX 8
  • libs: ControlsFX 8.0.6
  • IDE: IntelliJ
  • Platform: Win 7 + 8, MacOS-X

Mein Problem:
ControlsFX bietet die Möglichkeit eine Notification auf dem Desktop "aufpoppen" zu lassen. (ControlsFX Features // JavaFX News, Demos and Insight // FX Experience)
Dies ist bei mir der Fall wenn ich in meinem TrayIcon (AWT) einen eintrag im Popupmenü klicke.
Das funktioniert soweit auch problemlos, sofern denn mindestens ein JavaFX Fenster geöffnet ist. Allerdings benötige ich die Popups grade dann wenn das Fenster nicht offen ist. Hat da jemand eine Idee wie ich das Regeln kann?

Aufruf des Popups
Java:
if (jnlpData.isPopup() && !jnlpData.getNote().isEmpty()) {
                System.out.println("TEST");
                Application.invokeLater(() -> {
                    Notifications.create()
                            .title("Ihre Notiz")
                            .text(jnlpData.getNote())
                            .hideAfter(Duration.INDEFINITE)
                            .show();
       });
}

Stacktrace
Code:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Owner window must not be null
	at javafx.stage.PopupWindow.validateOwnerWindow(PopupWindow.java:916)
	at javafx.stage.PopupWindow.show(PopupWindow.java:412)
	at org.controlsfx.control.Notifications$NotificationPopupHandler.show(Notifications.java:437)
	at org.controlsfx.control.Notifications$NotificationPopupHandler.show(Notifications.java:318)
	at org.controlsfx.control.Notifications.show(Notifications.java:264)
	at de.adesso.cometjnlp.tray.CometJNLPMenuItem.lambda$null$0(CometJNLPMenuItem.java:50)
	at de.adesso.cometjnlp.tray.CometJNLPMenuItem$$Lambda$13/727677132.run(Unknown Source)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
	at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
	at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
	at java.lang.Thread.run(Thread.java:745)


Ich gebe mich auch gerne mit gezielten Denkanstößen zufrieden! Immerhin will ich mir das ja am Ende auch im Kopf behalten!
Vielen dank im Vorraus!

Toriath
 
Zuletzt bearbeitet:

dzim

Top Contributor
Da ich selbst noch nicht mit TrayIcons gearbeitet habe:
Vielleicht macht die Kombination AWT/JavaFX hier doch noch Probleme. Wenn man nach "javafx tray icon" sucht, findet man ein paar Links, die einem die TrayIcons von JavaFX zeigen könnten (falls das in deiner Anwendung überhaupt möglich ist - wenn es eine AWT/Swing-Anwendung ist, wohl eher nicht).

http://javafx-demos.googlecode.com/...swingawtintegration/JavaFXOnTrayIconDemo.java
Java:
package com.ezest.javafx.demogallery.swingawtintegration;

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 java.awt.event.MouseAdapter;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.control.Label;
import javafx.scene.control.TextFieldBuilder;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.StackPaneBuilder;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;

public class JavaFXOnTrayIconDemo extends Application {

	Stage stage;
	Scene scene;
	StackPane root;
	private EventHandler<MouseEvent> mousePressEvent;
	private EventHandler<MouseEvent> mouseDraggedEvent;
	private double startDragX;
	private double startDragY;
	private double startNodeX;
	private double startNodeY;

	private TrayIcon trayIcon;

	public static void main(String[] args) {
		Application.launch(args);
	}

	@Override
	public void start(final Stage stage) throws Exception {
		this.stage = stage;
		Platform.setImplicitExit(false);
		configureScene();
		configureStage();

		StackPane sp = StackPaneBuilder
				.create()
				.maxHeight(40)
				.maxWidth(100)
				.style("-fx-background-color:red;-fx-border-width:1px;-fx-border-color:black;-fx-background-radius:5px;-fx-border-radius:5px;-fx-cursor:hand;")
				.children(new Label("Add Note")).build();
		sp.setOnMouseClicked(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent arg0) {
				CustomPopUp p = new CustomPopUp(root);
				p.setTranslateX(600);
				p.setTranslateY(200);
				initEventHandlers(p);
				root.getChildren().add(p);
			}
		});
		root.getChildren().add(sp);
	}

	private void configureStage() {
		stage.setTitle(this.getClass().getSimpleName());
		stage.setX(0);
		stage.setY(0);
		stage.setWidth(Screen.getPrimary().getVisualBounds().getWidth());
		stage.setHeight(Screen.getPrimary().getVisualBounds().getHeight());
		stage.setScene(this.scene);
		stage.initStyle(StageStyle.TRANSPARENT);
		stage.show();
		createTrayIcon(stage);
	}

	private void configureScene() {
		root = StackPaneBuilder.create().style("-fx-border-width:0px;-fx-border-color:red;").alignment(Pos.TOP_LEFT).build();
		BorderPane bp = new BorderPane();
		bp.setCenter(root);
		bp.autosize();
		this.scene = new Scene(bp, Color.TRANSPARENT);
	}

	public void createTrayIcon(final Stage stage) {
		if (SystemTray.isSupported()) {
			// get the SystemTray instance
			SystemTray tray = SystemTray.getSystemTray();
			// load an image
			java.awt.Image image = Toolkit.getDefaultToolkit().getImage(JavaFXOnTrayIconDemo.class.getResource("/images/mglass.gif"));
			stage.getIcons().add(new Image("/images/notes-icon.png"));
			stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
				@Override
				public void handle(WindowEvent t) {
					Platform.runLater(new Runnable() {
						@Override
						public void run() {
							if (SystemTray.isSupported()) {
								stage.hide();
								showProgramIsMinimizedMsg();
							} else {
								System.exit(0);
							}
						}
					});
				}
			});
			// 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) {
					System.exit(0);
				}
			};

			ActionListener showListener = new ActionListener() {
				@Override
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Platform.runLater(new Runnable() {
						@Override
						public void run() {
							stage.show();
							CustomPopUp p = new CustomPopUp(root);
							p.setTranslateX(600);
							p.setTranslateY(200);
							initEventHandlers(p);
							root.getChildren().add(p);
						}
					});
				}
			};

			// create a popup menu
			PopupMenu popup = new PopupMenu();

			MenuItem showItem = new MenuItem("Show");
			showItem.addActionListener(showListener);
			popup.add(showItem);

			MenuItem closeItem = new MenuItem("Exit");
			closeItem.addActionListener(closeListener);
			popup.add(closeItem);

			trayIcon = new TrayIcon(image, "PostItNote", popup);
			trayIcon.addActionListener(showListener);
			trayIcon.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(java.awt.event.MouseEvent e) {
					System.out.println(e.getButton());
					Platform.runLater(new Runnable() {
						@Override
						public void run() {
							System.out.println(23);
							stage.show();
						}
					});
				}
			});
			
			try {
				tray.add(trayIcon);
			} catch (AWTException e) {
				System.err.println(e);
			}

		}
	}

	public void showProgramIsMinimizedMsg() {
		trayIcon.displayMessage("Message.", "Application is still running.You can access from here.", TrayIcon.MessageType.INFO);
	}

	/**
	 * Sets the mouse events on the provided component.
	 * 
	 * @param comp
	 *            CustomPopUp on which the mouse listeners need to be set.
	 */
	private void initEventHandlers(final CustomPopUp popUp) {
		mousePressEvent = new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent me) {
				popUp.toFront();
				// Registering the co-ordinates.
				startDragX = me.getSceneX();
				startDragY = me.getSceneY();
				startNodeX = popUp.getTranslateX();
				startNodeY = popUp.getTranslateY();
			}
		};

		mouseDraggedEvent = new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent me) {
				double xTr = startNodeX + (me.getSceneX() - startDragX);
				double yTr = startNodeY + (me.getSceneY() - startDragY);
				double mxDiff = root.getWidth() - popUp.getWidth();
				double myDiff = root.getHeight() - popUp.getHeight();
				xTr = xTr < 0 ? 0 : (xTr > mxDiff ? mxDiff : xTr);
				yTr = yTr < 0 ? 0 : (yTr > myDiff ? myDiff : yTr);

				popUp.setTranslateX(xTr < 0 ? 0 : xTr);
				popUp.setTranslateY(yTr);
			}
		};

		popUp.addEventHandler(MouseEvent.MOUSE_DRAGGED, mouseDraggedEvent);
		popUp.addEventHandler(MouseEvent.MOUSE_PRESSED, mousePressEvent);
	}

	/**
	 * Custom pop up class.
	 */
	class CustomPopUp extends StackPane {
		final StackPane parent;
		final String style = "-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 8, 0.0 , 0 , 2 );"
				+ "-fx-background-color:yellow;-fx-border-width:1px;-fx-border-color:black;"
				+ "-fx-background-radius:5px;-fx-border-radius:5px;";

		public CustomPopUp(StackPane parentWindow) {
			super();
			this.parent = parentWindow;
			setMaxHeight(200);
			setMaxWidth(200);
			getChildren().add(
					StackPaneBuilder.create().style(style).minHeight(200).minWidth(200).alignment(Pos.TOP_RIGHT)
							.children(ButtonBuilder.create().text("Close").onAction(new EventHandler<ActionEvent>() {
								@Override
								public void handle(ActionEvent paramT) {
									parent.getChildren().remove(CustomPopUp.this);
								}
							}).build(), TextFieldBuilder.create().translateY(20).build()).build());
		}
	}
}
(Diese Anwendung hat keine Höhe und Breite, aber es existiert eine Stage, damit sollte deine Notification kein Problem mehr haben.)

Alternativ findet man auf der JavaDoc vom ControlsFX-Projekt ( ControlsFX Project 8.0.6 ) für die Klasse "Notifications" die Möglichkeit explizit einen Owner anzugeben (als Object - ich nehme an, damit kann man es innerhalb der Anwendung aufpopen lassen). Vielleicht kannst du hier ja eine Stage mit Höhe und Breite Null angeben...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Systray, Notification AWT, Swing, JavaFX & SWT 9
Redfrettchen JTextArea während einer DocumentListener Notification ändern AWT, Swing, JavaFX & SWT 5
T Gui öffnet nicht AWT, Swing, JavaFX & SWT 2
O showConfirmDialog öffnet sich nicht AWT, Swing, JavaFX & SWT 3
S JavaFX Scene öffnet sich nicht AWT, Swing, JavaFX & SWT 3
B [Problem] Java öffnet Word-Datein nicht AWT, Swing, JavaFX & SWT 14
J *.jar öffnet PDF-Datei nicht AWT, Swing, JavaFX & SWT 35
T Frame öffnet nicht AWT, Swing, JavaFX & SWT 1
B Hauptfenster öffnet sich mehrmals AWT, Swing, JavaFX & SWT 9
Tausendsassa Frame öffnet aber zeigt keinen Inhalt... AWT, Swing, JavaFX & SWT 10
K Java Button öffnet neues Fenster AWT, Swing, JavaFX & SWT 5
A Swing JFrame öffnet nicht vollständig AWT, Swing, JavaFX & SWT 1
B Swing focusGained öffnet sich zwei mal AWT, Swing, JavaFX & SWT 3
W Swing JFrame Parent öffnet Child AWT, Swing, JavaFX & SWT 1
S JFileChooser öffnet den falschen Ordner AWT, Swing, JavaFX & SWT 4
Helgon JFileChooser öffnet sich 2x AWT, Swing, JavaFX & SWT 12
T neuer JFrame öffnet sich erst wenn Methode die dahinerliegt abgeschlossen ist. BUG? AWT, Swing, JavaFX & SWT 4
U Frame öffnet anderes Frame: Methode auslagern AWT, Swing, JavaFX & SWT 26
L 2 Monitore, Fenster öffnet sich im falschen Monitor AWT, Swing, JavaFX & SWT 3
J JFileChooser öffnet sich in manchen Fällen extrem langsam! AWT, Swing, JavaFX & SWT 12
D Aufgeführte jar-Datei, JDialog öffnet sich nicht AWT, Swing, JavaFX & SWT 13
B DateComboBox öffnet sich hinter JTextarea. AWT, Swing, JavaFX & SWT 10
G PrintJob öffnet sich auf manchen PCs nicht AWT, Swing, JavaFX & SWT 5
L F10 Taste öffnet das Menü AWT, Swing, JavaFX & SWT 7
M JComboBox Popup öffnet nicht AWT, Swing, JavaFX & SWT 6
J JList - doppelklick auf item -> neues fenster öffnet sich AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben