# JFrame per klick in Systemtray Icon unsichtbar machen/schließen und wieder starten



## pel (15. September 2007)

Hallo,

Ich habe mein Programm in die SystemTray gesetzt. Habe dazu 2 MenuItem`s erstellt:

"Programmfenster anzeigen"
"Programm beenden"

Kann auf die Einträge klicken und Text-Ausgaben machen klappt alles. Jetzt möchte noch folgendes erreichen:

1. Beim Start der Anwendung soll das Fenster nicht sichtbar sein, sondern es soll sich sozusagen verstecken in der SystemTray Leiste

Das würde ich mit 
	
	
	



```
myWindow.setVisible(false);
```
 machen. Doch...

2. Wenn ich das Fenster wieder sichtbar machen will mit 
	
	
	



```
myWindows.setVisible(true);
```
dann bekomme ich diese Fehlermeldung:


```
Das Programmfenster wird angezeigt!
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at ImageListePanel$2.actionPerformed(ImageListePanel.java:218)
	at java.awt.MenuItem.processActionEvent(Unknown Source)
	at java.awt.MenuItem.processEvent(Unknown Source)
	at java.awt.MenuComponent.dispatchEventImpl(Unknown Source)
	at java.awt.MenuComponent.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
```

3. Dazu möchte ich noch eine Meldung anzeigen lassen über dem Icon in der SystemTray Anzeige, doch die Meldung erscheint nicht  :


```
trayIcon.displayMessage("Action Event","Hallo!",TrayIcon.MessageType.INFO);
```

Das ist der ganze Code:

*Hauptfenster*

```
public class MainWindow extends JFrame
{   
	static final long serialVersionUID = 1L;	
    
    public MainWindow() throws AWTException {
        
    	super("Rembo Image Lister");
        // setIconImage(new ImageIcon("images/Dir.gif").getImage());
        UIManager.put("ProgressBar.selectionBackground", Color.black);
        
        ImageListePanel  IL = new ImageListePanel();
        SettingsPanel SP = new SettingsPanel();       
       
        IL.setSP(SP);
        SP.setIL(IL); 
        JTabbedPane jtp = new JTabbedPane();
        jtp.addTab("<html><font size=5>Image-Liste</font size></html>", IL);
        jtp.addTab("<html><font size=5>Image-Verwaltung</font size></html>", SP);
        add(jtp);
    }
    
    class Listener implements WindowListener
    {
	  public void windowActivated(WindowEvent arg0)
      {}
      public void windowClosed(WindowEvent arg0)
      {}
      public void windowClosing(WindowEvent arg0)
      {  
    	  int n = JOptionPane.showConfirmDialog(null,"Möchten Sie Ihre Daten noch speichern?","Alles klar?",JOptionPane.YES_NO_OPTION);
	        
    	  if (n == 0)//YES
	      {
	        	System.out.println("speichern!");
	      }
	      if (n == 1)//NO
	      {
	    	  System.out.println("beenden");//return;
	      }      
      }
      public void windowDeactivated(WindowEvent arg0)
      {}
      public void windowDeiconified(WindowEvent arg0)
      {}
      public void windowIconified(WindowEvent arg0)
      {} 
      public void windowOpened(WindowEvent arg0)
      {}     
    } 
    
    public static void main(String args[]) throws AWTException
    {
        try
        {
            Color  defForeground = new Color(0,140,222);
            UIManager.put("Label.foreground",defForeground);
            JFrame.setDefaultLookAndFeelDecorated(true); 

            UIDefaults defaults = UIManager.getDefaults();
            Font arial = new Font("Arial", 0, 11);
            defaults.put("MenuItem.font", arial);
            defaults.put("TabbedPane.font", arial);
            defaults.put("TextField.font", arial);
            defaults.put("Label.font", arial);
            defaults.put("Button.font", arial);
            defaults.put("ComboBox.font", arial);
            defaults.put("Panel.font", arial);
            
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        
        MainWindow myWindow = new MainWindow();
        myWindow.setSize(1000,720);
        myWindow.setLocationRelativeTo(null);
        myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myWindow.setResizable(false);
        myWindow.setVisible(false);        
        myWindow.addWindowListener(myWindow.new Listener());         
      
    } 
    
}
```


*Der Tabreiter im JFrame(Hauptfenster)*

```
public class ImageListePanel extends JPanel implements ActionListener , ListSelectionListener
{
   
	static final long serialVersionUID = 1L;
   
	private SettingsPanel settings;
          
    private  JButton loadListBT = new JButton("Liste laden");
    private  JButton saveListBT = new JButton("Liste speichern");   
      
    private  JButton addRowBT		= new JButton();
    private  JButton delRowBT		= new JButton(); 
    
    private DefaultListModel listModel = new DefaultListModel();
    private JList liste = new JList(listModel);
    private JScrollPane listbereich = new JScrollPane(liste);
    private String[] spaltennamen = {"Status" , "Gruppe" , "Programm" , "Aufgabe" , "Datenträger" };
    private String[][] tabellendaten = new String [700][5];
   
    DefaultTableModel dm;
    JTable tabelle;    
    MainWindow myWindow;
    TrayIcon trayIcon = null;
    PopupMenu popup = new PopupMenu();
    MenuItem anzeigenMI = new MenuItem("Programmfenster anzeigen");
    MenuItem exitMI = new MenuItem("Programm beenden");
    
    public ImageListePanel() throws AWTException
    {
      
    	setLayout(null);
        
        add(loadListBT);
        add(saveListBT);       
        add(listbereich);
        add(addRowBT);
        add(delRowBT);        
        
        listbereich.setBounds(826,0,160,340);
        loadListBT.setBounds(826,468,158,60);
        saveListBT.setBounds(826,529,158,60);       
        addRowBT.setBounds(826,341,40,40);
        delRowBT.setBounds(867,341,40,40);
        
        loadListBT.setIcon(new ImageIcon("images/pasteurl.png"));
        saveListBT.setIcon(new ImageIcon("images/refresh.png"));        
        addRowBT.setIcon(new ImageIcon("images/add.row.png"));
        delRowBT.setIcon(new ImageIcon("images/delete.row.png"));
          
              
        dm = new DefaultTableModel(tabellendaten,spaltennamen);
        tabelle = new JTable( dm ){
        	/**
			 * 
			 */
			private static final long serialVersionUID = 1L; 
					Class[] types = new Class [] {        			
                    Boolean.class, String.class, String.class, String.class, String.class
                };
            @SuppressWarnings("unchecked")
			public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
            
        	public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex)
        	{
				Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
				
				/*---------------------------------------------------------------------------*/
				
				if (rowIndex % 2 == 0 && !isCellSelected(rowIndex,vColIndex))
				{
	                c.setBackground(new Color (245,245,245));
	            }
				else if (rowIndex % 2 == 0)
				{
					c.setBackground(new Color (245,245,245));
				}
				else
				{
	                c.setBackground(new Color (255,255,255));
	            }
				/*----------------------------------------------------------------------------*/
				
				
				if(isRowSelected(rowIndex))
				{
					return c;
				}	
				
				return c;
				
			}
		};
		
		
		DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);         
              
        JScrollPane scrollPane = new JScrollPane( tabelle );
        add(scrollPane);
        scrollPane.setBounds(0,0,826,650);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        
        tabelle.getColumnModel().getColumn(1).setCellRenderer(renderer);
		//tabelle.setRowSelectionAllowed(true);
		//tabelle.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
		tabelle.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);tabelle.setRowHeight(22);         
        tabelle.setAutoCreateRowSorter(true);      
        
        listbereich.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        listbereich.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        liste.setCellRenderer(new Renderer());
        
        listModel.addElement("MPG Lehrer 125");
        listModel.addElement("AEG Schüler xp");
        listModel.addElement("RHS Lehrer 112");
        listModel.addElement("AEG Schüler xp");
        listModel.addElement("OHG Lehrer 125");
        listModel.addElement("MPG Lehrer 125");
        listModel.addElement("EKS Schüler 120");
        listModel.addElement("MPG Lehrer 125");
        listModel.addElement("EDS Lehrer 120");
        listModel.addElement("AEG Schüler xp");
        listModel.addElement("MPG Lehrer 125");
        listModel.addElement("AEG Schüler xp");
        listModel.addElement("MPG Lehrer 125");
        listModel.addElement("EKS Schüler 120");
        listModel.addElement("MPG Lehrer 125");
        listModel.addElement("EDS Lehrer 120");
        listModel.addElement("AEG Schüler xp");
        listModel.addElement("MPG Lehrer 125");
        listModel.addElement("AEG Schüler xp");
        
        addRowBT.addActionListener(this);
        delRowBT.addActionListener(this);
        liste.addListSelectionListener((ListSelectionListener) this);
        setColumnWidth();
        initSystemTray();
    }
    /*
     * --------------------------- Constructor End ---------------------------------------- * 
     */
    
    public void initSystemTray() throws AWTException
    {
    	
    	if (SystemTray.isSupported())
        {
            
    		
    		SystemTray tray = SystemTray.getSystemTray();
            Image image = Toolkit.getDefaultToolkit().getImage("refresh.png");

            /*MouseListener mouseListener = new MouseListener()
            {                
                public void mouseClicked(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse clicked!");
                }
                public void mouseEntered(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse entered!");                 
                }
                public void mouseExited(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse exited!");                 
                }
                public void mousePressed(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse pressed!");                 
                }
                public void mouseReleased(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse released!");                 
            }

            };*/
           // trayIcon.addMouseListener(mouseListener);
            
            popup.add(anzeigenMI);
            popup.add(exitMI);
            
            trayIcon = new TrayIcon(image, "Tray Demo", popup);
            tray.add(trayIcon);
            trayIcon.setImageAutoSize(true);
            
            
            ActionListener anzeigenListener = new ActionListener() {
                public void actionPerformed(ActionEvent e)
                {
                	if (e.getSource().equals(anzeigenMI))
            	    { 
                    	System.out.println("Das Programmfenster wird angezeigt!");
                    	myWindow.setVisible(true);
                    }	
                }
            };
            
            ActionListener exitListener = new ActionListener() {
                public void actionPerformed(ActionEvent e)
                {
                	     System.out.println("Das Programm wird beendet!");
                	     System.exit(0);
                }
                };            
           
            
            anzeigenMI.addActionListener(anzeigenListener);
            exitMI.addActionListener(exitListener);
            //trayIcon.addActionListener(actionListener);
            trayIcon.displayMessage("Action Event","An Action Event Has Been Peformed!",TrayIcon.MessageType.INFO);

        }
        else 
        {
            System.err.println("System tray is currently not supported.");
        }    	
    }
    
    public void setSP(SettingsPanel object) {
        this.settings = object;
    }
    public void valueChanged( ListSelectionEvent e )
    {
        if(!e.getValueIsAdjusting())
        {
            
        }
    }
    public void setColumnWidth() {
        tabelle.getColumnModel().getColumn(0).setPreferredWidth(40);
        tabelle.getColumnModel().getColumn(1).setPreferredWidth(50);
        tabelle.getColumnModel().getColumn(2).setPreferredWidth(100);
        tabelle.getColumnModel().getColumn(3).setPreferredWidth(500);
        tabelle.getColumnModel().getColumn(4).setPreferredWidth(100);
    }
    public void actionPerformed(final ActionEvent e)
    {
        
        if(e.getSource().equals( addRowBT))
        {      	
        	dm.insertRow(tabelle.getSelectedRow()+1, new Object[]{});
        }
        if(e.getSource().equals( delRowBT))
        {      	
        	if(tabelle.getSelectedRow() == -1)
        	{        		
        	}
        	else
        	{
        		dm.removeRow(tabelle.getSelectedRow());
        	}	
        }
     }
    
    public void mousePressed(MouseEvent e)
    {
    	dm.setValueAt("fff",1,1);
    }
    
}
```


----------



## Florian Strienz (15. September 2007)

Hi,

ich habe deine Code mal kurz überflogen, aber wenn ich das richtig sehe erzeugts du dein Hauptfenster zwar oben in der Main-Methode

 MainWindow myWindow = new MainWindow();
        myWindow.setSize(1000,720);
        myWindow.setLocationRelativeTo(null);
        myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myWindow.setResizable(false);
        myWindow.setVisible(false);        
        myWindow.addWindowListener(myWindow.new Listener());     

du weisst es aber nicht unten deiner Variable für die Tray zu.

   JTable tabelle;    
    MainWindow myWindow;
    TrayIcon trayIcon = null;

daher kommt die Nullpointer exception. Übergeb mal an den Konstruktor deiner unteren Klasse das fenster das du oben erzeugst und weise es myWindow zu.

**********************

Ich würde das hier auch nicht machen, wenn du dein Fenster über die Tray steuern willst:

myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Immer wenn du dein Hauptfenster per X schließt, würde dein komplettes Programm inklusive Tray geschlossen werden. Mach lieber DISPOSE_ON_CLOSE

Ich hoffe das hilft dir erstmal weiter
Gruß Kaiser


----------



## pel (15. September 2007)

Hi,

erstmal danke für deine Hilfe!

Eins verstehe nicht, was meinst du mit oben und unten?



> ich habe deine Code mal kurz überflogen, aber wenn ich das richtig sehe erzeugts du dein Hauptfenster zwar oben in der Main-Methode
> 
> MainWindow myWindow = new MainWindow();
> myWindow.setSize(1000,720);
> ...







> JTable tabelle;
> MainWindow myWindow;
> TrayIcon trayIcon = null;
> 
> daher kommt die Nullpointer exception. Übergeb mal an den Konstruktor deiner unteren Klasse das fenster das du oben erzeugst und weise es myWindow zu.



obiger Satz verwirrt mich. Konstruktor meiner unteren KLassen ? meinst du so:


```
MainWindow myWindow;
    TrayIcon trayIcon = null;
    PopupMenu popup = new PopupMenu();
    MenuItem anzeigenMI = new MenuItem("Programmfenster anzeigen");
    MenuItem exitMI = new MenuItem("Programm beenden");
    
    public ImageListePanel(MainWindow myWindow) throws AWTException
    {
        this.myWindow = myWindow;
    	setLayout(null);
```




> Ich würde das hier auch nicht machen, wenn du dein Fenster über die Tray steuern willst:
> myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



Ich weiß, das ist noch ein überbleibsel aus der Zeit, als das Ding ohne tray laufen sollte ;-)

.dispose() ist ja deprecated weißt du was man stattdessen nimmt ? Bzw. andersrum gefragt... wenn ich das FEnster schließe mit klick auf das "x" rechts oben und das fenster "geht in" die Systemtray, dann soll das Programm dennoch nebenher online sein, da es datumsüberprüfungen vornehmen soll.


----------



## Florian Strienz (15. September 2007)

Sorry für die wirre Antwort, hatte das nur so nebenher schnell getippt.

mit oben meinte ich deine Fenster Klasse, mit unten deine Tray Klasse.

probiere mal statt

```
ImageListePanel  IL = new ImageListePanel();
```
das

```
ImageListePanel  IL = new ImageListePanel(this);
```
in deiner Fensterklasse

und in deiner Trayklasse statt

```
public ImageListePanel() throws AWTException
```
das

```
public ImageListePanel(MainWindow mainWindow) throws AWTException{
...
myWindow=mainWindow;
...
}
```

Wenn das nicht hilft, muss ich mir mal dein Programm im Eclipse aufrufen und direkt kucken.

Eventuell solltest du dein Programm etwas aufräumen. Programm und Window/Tray solltest du entkoppeln.


----------



## pel (15. September 2007)

> Wenn das nicht hilft, muss ich mir mal dein Programm im Eclipse aufrufen und direkt kucken.



super hat funktioniert.



> Eventuell solltest du dein Programm etwas aufräumen. Programm und Window/Tray solltest du entkoppeln.



Wenn das Programm am Anfang das myWindow.setVisible(false) 
ausführt ist es ja unsichtbar.

Wenn das Programm an Anfang das myWindow.dispose() ausführen WÜRDE, dann ist das Fenster auch unsichtbar 

Wo ist der Unterschied ? Klar schaue ich in der Api nach steht dispose = ressourcen freigeben doch das erklärt wenig... bedeutet dies das Fenster wird nicht angezeigt, da es aus dem Speicher entfernt (ressource freigegeben) wurde und daher nichts mehr angezeigt werden kann ?

Wie würdest du das grob mit der Tray entkkoppeln?


----------



## Florian Strienz (15. September 2007)

Klasse, freut mich das es funktioniert hat. Mein erster Beitrag hier im Forum. 

mit setVisible steuerst du ob ein Fenster angezeigt wird oder nicht. Wenn du bei einem Fenster setVisible(false) setzt, dann siehst du das Fenster zwar nicht, es ist aber noch da und der Garbage Collector der VM wird es nicht aus dem Speicher entfernen.

Mit dispose sagst du, dieses Fenster werde ich so nicht mehr benötigen. Wenn der Garbage Collector jetzt aufräumt, wird auch das Fenster komplett aus dem Speicher elemeniert.

Du solltest also bei deinem Hauptfenster einen eigenen closing Event machen, der das Fenster nur "unsichtbar" macht.

Zum Thema aufräumen (das ist kompliziert):
Normalerweise wird keine Programmlogik in ein Fenster gepackt. Man sollte nach dem MVC Pattern arbeiten (Model View Control). Wobei das für Anfänger doch recht undurchsichtig zu beginn ist. Google einfach mal danach. Ich finde es ist nirgends so gut erklärt wie in dem Buch "Entwurfsmuster von Kopf bis Fuss".

Zu Beginn ist es leichter den Controler weg zulassen.

Mach dir eine Applicationsklasse in der deine ganze Programm logik drin ist und alles "steuert" (der Gui ist ja nur für uns Menschen, die Anwendung an sich kann ja auch unsichtbar im Hintergrund laufen) .

Dort kannst du auch das Fenster erzeugen. Gib dem Fenster eine Referenz auf deine Apps-Klasse (das Model), damit du die Applikation über das Gui Manipulieren kannst und das der Gui seine Daten die er anzeigen soll aus dem Model lesen kann.

Dein Trayicon kannst du auch in der Appsklasse erzeugen, dem gibst du auch eine Referenz auf deine Apps Klasse. In der Apps Klasse hast du dann eine Methode z.b. public void mainWindowVisible(boolean show){
...
}
die vom Trayicon aufgerufen werden kann um das Hauptfenster über deine Appsklasse zu steuern. 
Das hat den Vorteil, du kannst beliebig viele Klassen die das Hauptfenster sichtbar/unsichtbar machen sollen dann an deine Appsklasse hängen und alle können dann diese Methode verwenden. 

Wenn du etwas manipulieren willst, rufen die Guis immer Methoden der  Appsklasse auf. Daten die Angezeigt werden, werden nur aus der Appsklasse gelesen.

Über dieses Thema könnte man Seiten füllen. Aber wenn du deinen Code sauber strukturierst, dann hat das nur Vorteile.


----------



## pel (15. September 2007)

> mit setVisible steuerst du ob ein Fenster angezeigt wird oder nicht. Wenn du bei einem Fenster setVisible(false) setzt, dann siehst du das Fenster zwar nicht, es ist aber noch da und der Garbage Collector der VM wird es nicht aus dem Speicher entfernen.
> 
> Mit dispose sagst du, dieses Fenster werde ich so nicht mehr benötigen. Wenn der Garbage Collector jetzt aufräumt, wird auch das Fenster komplett aus dem Speicher elemeniert.


 wenn das Fenster aus dem speicher weg ist (und in dem Fenster liegen ja beide Tabreiter und alles andere) nehme ich an kann ich auch keine Datumsüberprüfung mehr machen richtig?



> Du solltest also bei deinem Hauptfenster einen eigenen closing Event machen, der das Fenster nur "unsichtbar" macht.



Im Moment ist es ja so: wenn ich nun das Fenster nicht schließen möchte sondern einfach unsichtbar in den Traybereich legen möchte, dann wäre die windowClosing Methode ja auf jeden Fall falsch oder? Denn der Name sagt es ja schon das Fenster WIRD geschlossen... Wo sage ich dann welcher Methode, dass bei "x" klick rechts oben im Fenster oder wo fange ich das ab, dass das Fenster nicht geschlossen wird sondern ich das Fenster auf setVisible(false) setzen kann?

*MainWindow.class*


> class Listener implements WindowListener
> {
> public void windowClosing(WindowEvent arg0)
> {
> ...






> MVC


 Jo ich lerne gerade noch Ruby und da wird MVC von vornherein erklärt, während viele Java Bücher das Unterschlagen (z.B. OOP in Java von A.Niemann) oder kaum behandeln, daher habe ich mich darum auch nie wirklich gekümmert...

Weißt du warum bei mir kein Textnachricht angezeigt wird 


> trayIcon.displayMessage("Action Event","An Action Event Has Been Peformed!",TrayIcon.MessageType.INFO);


 Ich habe mich genau an die kurze Anleitung gehalten von: http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/systemtray/

dennoch wird bei mir nichts angezeigt

Danke für die MVC Behandlung, lese es mir später noch genauer durch.

Ein Zeichen dafür, dass bei Sun keiner die Tutorials testet:

trayIcon.setTooltip("I'm busy. Go away.");

Den Text habe ich von der offiziellen Sun site und es muss setToolTip heißen


----------



## Florian Strienz (15. September 2007)

pel hat gesagt.:


> wenn das Fenster aus dem speicher weg ist (und in dem Fenster liegen ja beide Tabreiter und alles andere) nehme ich an kann ich auch keine Datumsüberprüfung mehr machen richtig?


korrekt, so sollte es normalerweise sein. Ich habe dein Programm noch nicht ganz verstanden, was es machen sollte, aber damit genau sowas nicht passiert, Anwendung vom Fenster entkoppeln.



> Im Moment ist es ja so: wenn ich nun das Fenster nicht schließen möchte sondern einfach unsichtbar in den Traybereich legen möchte, dann wäre die windowClosing Methode ja auf jeden Fall falsch oder? Denn der Name sagt es ja schon das Fenster WIRD geschlossen... Wo sage ich dann welcher Methode, dass bei "x" klick rechts oben
> im Fenster oder wo fange ich das ab, dass das Fenster nicht geschlossen wird sondern
> ich das Fenster auf setVisible(false) setzen kann?
> 
> *MainWindow.class*


Dein Code ist leider "Kraut und Rüben".  

Schmeiss das Raus:
        myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
du fügst ja hier deinen eigenen WindowListener ein, der auf das Closing Event reagiert.     
        myWindow.addWindowListener(myWindow.new Listener());    

Jetzt ersetzte das

```
public void windowClosing(WindowEvent arg0)
      {  
    	  int n = JOptionPane.showConfirmDialog(null,"Möchten Sie Ihre Daten noch speichern?","Alles klar?",JOptionPane.YES_NO_OPTION);
	        
    	  if (n == 0)//YES
	      {
	        	System.out.println("speichern!");
	      }
	      if (n == 1)//NO
	      {
	    	  System.out.println("beenden");//return;
	      }      
      }
```

durch


```
public void windowClosing(WindowEvent arg0)
      {  
    	   arg0.getWindow().setVisible(false);
     }
```



> Jo ich lerne gerade noch Ruby und da wird MVC von vornherein erklärt, während viele Java Bücher das Unterschlagen (z.B. OOP in Java von A.Niemann) oder kaum behandeln, daher habe ich mich darum auch nie wirklich gekümmert...
> 
> Weißt du warum bei mir kein Textnachricht angezeigt wird
> Ich habe mich genau an die kurze Anleitung gehalten von: http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/systemtray/
> ...



Das mit der Message weiss ich leider nicht, ich habe die Tray bisher noch nicht benutzt. Ich würde mal ein kleines Testprogramm schreiben wo du nur die Systemtray testest, bevor du es in dein Hauptprogramm integrierst. 

Schau mal hier, vielleicht hilft dir das:
http://www.galileocomputing.de/open...14_013.htm#mjc88957a839d3e08ddb1dd7759b1eadb2

auch noch ein sehr gutes kostenloses Java-Buch gibt es hier
http://www.javabuch.de
schau dir da mal den WindowsClosingAdapter an, um zu verstehen, wie Java Fenster geschlossen werden.

Gruß
Kaiser


----------



## pel (15. September 2007)

> Schmeiss das Raus:
> myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
> du fügst ja hier deinen eigenen WindowListener ein, der auf das Closing Event reagiert.
> myWindow.addWindowListener(myWindow.new Listener());



stimmt jetzt fällts mir auch auf... *vor den Kopf schlag*  das JFrame.Exit_ON_CLOSE schließt das Fenster wenn auf das "X" geklickt wird rechts oben und nicht die Methode windowClosing, da kann ich "nur" sagen was passieren soll wenn einer auf das "X" klickt, hoffe das war jetzt richtig gesagt ^^

ok hat auf jeden Fall geklappt. Nun wird das Programm unsichtbargeladen, kann über die Tray angezeigt werden und wieder unsichtbar gemacht werden. Geschlossen wird das Programm komplett über das Traysymbol.


> Das mit der Message weiss ich leider nicht, ich habe die Tray bisher noch nicht benutzt. Ich würde mal ein kleines Testprogramm schreiben wo du nur die Systemtray testest, bevor du es in dein Hauptprogramm integrierst.



Ich probier den code mal in einer Extra anwendung aus. Mein PC tickt grad eh nicht richtig obwohl neu installiert etc... evtl können keine Popups angezeigt werden, da ich zuviel mit xp-antispy und so tools rumspielte 

Javainsel und Javabuch mag ich beide nicht, habe mir in der Buchhandlung jetzt das gekauft:

http://www.amazon.de/Java-6-Program...6058407?ie=UTF8&s=books&qid=1189869248&sr=8-6

habs neu für 40 euro bekommen ;-)

Danke für deine Hilfe warst echt gut! ;-)

Edit:

Also entweder bin ich zu blöd oder Sun...

Habe mal in eine neue Klasse den kompletten Code von Sun reinkopiert: http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/systemtray/

den imagepfad angepasst und das fenster wird angezeigt, ich bekomme keine Fehlermeldung dennoch sehe ich kein bild im traybereich? HAHA oh man... vllt. willst es auch mal probieren dann wissen wir wer belämmert ist ;-)  

komisches Forum für einen *Zwinker* emoticon ala ";-)" nimmt der foren code ein emoticon mit Sonnenbrille  Irgendwie nicht passend, scheint nicht mein Tag zu sein.


----------

