SystemTray zusammen mit JPopMenu verwenden

January

Mitglied
Hallo zusammen.
Nach langer, ergebnisloser Suche hoffe ich jetzt hier auf eine Antwort:

Ich möchte, dass bei einem Rechts- und Links-Klick auf das TrayIcon jeweils ein unterschiedliches JPopupMenu (nicht PopupMenu) erscheint. Da "TrayIcon" nur PopupMenu und das auch kein zweites Menü unterstützt, habe ich das jetzt so gelöst:
Code:
package test;

import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Image;
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.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

public class tray {

	final static SystemTray tray = SystemTray.getSystemTray();
	static TrayIcon trayIcon = null;
	final static JPopupMenu popupRechts = new JPopupMenu();
	final static JPopupMenu popupLinks = new JPopupMenu();
	final static JMenuItem itemLinks = new JMenuItem("Beispiel Links");
	final static JMenuItem itemRechts = new JMenuItem("Beispiel Rechts");
	final static JMenuItem beenden = new JMenuItem("Beenden");

	public static void traySymbol() {
		beenden.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				tray.remove(trayIcon);
			}
		});
		popupLinks.add(itemLinks);
		popupRechts.add(itemRechts);
		popupRechts.add(beenden);
		Runnable runner = new Runnable() {
			public void run() {
				if (SystemTray.isSupported()) {
					Image image = Toolkit.getDefaultToolkit().getImage(
							getClass().getResource("/icons/clock.png"));
					trayIcon = new TrayIcon(image, "PopUp-Text");
					trayIcon.addMouseListener(new MouseAdapter() {
						public void mouseReleased(MouseEvent e) {
							int klick = e.getButton();
							switch (klick) {
							case 1: // Links-Klick
								popupLinks.setLocation(e.getX(), e.getY());
								popupLinks.setInvoker(popupRechts);
								popupLinks.setVisible(true);
								break;
							case 2: // Mitte-Klick
								break;
							case 3: // Rechts-Klick
								popupRechts.setLocation(e.getX(), e.getY());
								popupRechts.setInvoker(popupRechts);
								popupRechts.setVisible(true);
								break;
							default:
								System.out.println("Unbekannter Maus-Klick!");
							}
						}
					});
					try {
						tray.add(trayIcon);
					} catch (AWTException e) {
						System.err.println("Oeffnen im Tray nicht moeglich");
					}
				} else {
					System.err.println("Tray nicht verfuegbar");
				}
			}
		};
		EventQueue.invokeLater(runner);
	}
	
	public static void main(String[] args) {
		traySymbol();
	}
}

Nun zu meinem Problem: Wenn ich eins der Menüs anwähle kann ich es nicht durch "danebenklicken" oder esc. wieder abwählen. Es bleibt so lange offen bis ich einen Eintrag angeklickt habe.
Hat jemand für euch eine Lösung für dieses Problem? Wenn es eine besser Lösung gibt zwei JPopupMenu mit einem Tray-Symbol zu verwenden immer her damit. Bin noch ein ziemlicher Java-Anfänger.

Danke! January
 
Howdie.

Ich hab grad mal ein kurzes Sample geschrieben, um dein Problem zu testen. Dabei hab ich folgendes festgestellt: Ein Klick außerhalb des Popups deaktiviert dieses lediglich, wenn der Klick auf der Invoker-Komponente geschieht. In meinem Beispiel habe ich ein Hauptfenster (JFrame), das ich dem Popup-Aufruf im MouseListener als Invoker mitgegeben habe - dann funktioniert es. Ich poste hier mal den relevanten Ausschnitt aus meinen Sample-Code:
Java:
class MySample extends JFrame {
     public MySample(){
	try {
	              // JFrame startup hier
                            ...
                          
                            // Sample
		SystemTray tray = SystemTray.getSystemTray();
		TrayIcon icon = new TrayIcon(testImage);
		tray.add(icon);
		icon.addMouseListener(new MouseListener(){
			public void mouseClicked(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {}
	
			public void mouseReleased(MouseEvent e) {
				
				switch(e.getButton()){
					case MouseEvent.BUTTON1:
						
						JPopupMenu pop1 = new JPopupMenu();
						pop1.add(new JMenuItem("menu 1"));
						pop1.add(new JMenuItem("menu 2"));
						pop1.show(MySample.this, e.getX(), e.getY());
						
						break;
					case MouseEvent.BUTTON3:
						
						JPopupMenu pop2 = new JPopupMenu();
						pop2.add(new JMenuItem("menu 3"));
						pop2.add(new JMenuItem("menu 4"));
						pop12.show(MySample.this, e.getX(), e.getY());
						
						break;
				}
			}
		});
	} catch (IOException e) {
		e.printStackTrace();
	} catch (AWTException e) {
		e.printStackTrace();
	}

     }
}

Und das ist jetzt kein guter Code!
Das ist jetzt wirklich nur zum Testen, nimm dir das nicht als Grundlage für weitere Entwicklungen, ja?
Da du Java-Anfänger bist, würde ich dir dringend empfehlen, erstmal einen Grundkurs durchzuarbeiten. Hier auf dem Board gibt es da zahlreiche Hilfestellungen. Z.B. solltest du dir bald abgewöhnen, alle verwendeten Komponenten statisch anzulegen. Auch das Runnable ist bei einer Start-Konfiguration nicht nötig, sowas wird erst sinnvoll, wenn du Multi-Threading realisieren willst.

Gruß und viel Erfolg
miffi
 
Zuletzt bearbeitet von einem Moderator:
wie wäre es mit folgendem Lösungsansatz?
sobald du das Popupmenu verlässt wird es direkt geschlossen, oder du startest einen timer der nach x ms außerhalb des Menus dieses schließt
da ich meinen Ansatz aber gerade nicht testen kann, weiß ich nicht ob dieser auch so funktioniert
 
Da habe ich mich wohl etwas zu früh gefreut. Jetzt taucht (logischerweise) immer zusätzlich zu dem Traysymbol ein Fenster auf, wenn ich das Programm starte. Das Programm soll allerdings nur in dem Systemtray erreichbar sein. Gibt es eine Möglichkeit das Fenster auszublenden? setVisible(false) funktioniert nicht.
Danke schon im Voraus!
January

Code:
package test;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

public class traytest extends JFrame {

	private static final long serialVersionUID = -335717604718181053L;
	static SystemTray tray;
	static TrayIcon trayIcon;
	static JPopupMenu popupRechts;
	static JPopupMenu popupLinks;
	static JMenuItem itemRechts;
	static JMenuItem itemLinks;
	
	public traytest() {
		super("Dieses Fenster müsste weg");
		this.setSize(400,100);
		if (SystemTray.isSupported()) {
			Image image = Toolkit.getDefaultToolkit().getImage(
					getClass().getResource("/icons/clock.png"));
			trayIcon = new TrayIcon(image, "Popup-Text");
			trayIcon.addMouseListener(new MouseListener() {
				public void mouseReleased(MouseEvent e) {
					switch (e.getButton()) {
					case MouseEvent.BUTTON1: // Linksklick
						popupLinks = new JPopupMenu(); 
						itemLinks = new JMenuItem("links");
						popupLinks.add(itemLinks);
						popupLinks.show(traytest.this, e.getX(), 0);
						break;

					case MouseEvent.BUTTON3: // Rechtsklick
						popupRechts = new JPopupMenu(); 
						itemRechts = new JMenuItem("rechts");
						popupRechts.add(itemRechts);
						popupRechts.show(traytest.this, e.getX(), 0);
						break;
					}
				}

				public void mouseClicked(MouseEvent e) {
				}

				public void mouseEntered(MouseEvent e) {
				}

				public void mouseExited(MouseEvent e) {
				}

				public void mousePressed(MouseEvent e) {
				}
			});
			try {
				tray = SystemTray.getSystemTray();
				tray.add(trayIcon);
			} catch (AWTException e) {
				System.err.println("Oeffnen im Tray nicht moeglich");
			}
		} else {
			System.err.println("Tray nicht verfuegbar");
		}
	}

	public static void main (String ... args){
		traytest start = new traytest();
		start.setVisible(true);
	}
}
 

Neue Beiträge

Zurück