Is there any way I can check if a system tray already exists as at the moment If I keep clicking the Jar file to create a system tray then multiple occurrences appear, which means multiple programs are run.
Welcome to the Java Programming Forums
The professional, friendly Java community. 21,500 members and growing!
The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.
>> REGISTER NOW TO START POSTING
Members have full access to the forums. Advertisements are removed for registered users.
Is there any way I can check if a system tray already exists as at the moment If I keep clicking the Jar file to create a system tray then multiple occurrences appear, which means multiple programs are run.
If you only want one version of a program running at a time, then the program needs to detect when another version has been started. One way is to use a ServerSocket at a special port to detect the other one. The system only allows one. Make a small, simple program to test how that works.
If you don't understand my answer, don't ignore it, ask a question.
keepStriving (December 13th, 2013)
Another way I've used:
Check if certain file exists, if already created then can't use system tray, if file has not created then create and run system tray, when exiting system tray delete file.
--- Update ---
I have got it to partially work with server socket in that multiple instances of system tray class can't be invoked at the same time though for some reason it does not appear as an icon on the system tray even though it my be running in eclipse.
public class SystemTrayPostItNotes{ public static void main(String[]args)throws Exception{ try{ final ServerSocket socket = new ServerSocket(5000); final Socket clientSocket = socket.accept(); PopupMenu popUp = new PopupMenu(); MenuItem exit = new MenuItem("Exit"); exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ try { clientSocket.close(); socket.close(); }catch (IOException e) { System.out.println("Can't close"); } System.exit(0); } }); popUp.add(exit); Image image = Toolkit.getDefaultToolkit().getImage("C:\\Users\\keepStriving\\Desktop\\GeoGebra_icon_edit.png"); TrayIcon trayIcon = new TrayIcon(image, "Post It Notes Program", popUp); SystemTray.getSystemTray().add(trayIcon); trayIcon.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ MainGuiNotes notes = new MainGuiNotes(); } }); }catch(Exception except){ System.out.println("Already in use"); } } }
What happened when you created a test program that used the ServerSocket when you started the program for the second time?
If you don't understand my answer, don't ignore it, ask a question.
final ServerSocket socket = new ServerSocket(5000); final Socket clientSocket = socket.accept();
can you not put this at the end so it will set the tray up first as I think the program blocks when you issue socket.accept().
Put this at the end so it sets the tray up and then blocks.
Andrea, www.andbin.net — SCJP 5 (91%) – SCWCD 5 (94%)
Useful links for Java beginners – My new project Java Examples on Google Code
The first system tray keeps running and I get an output that there is already one running so can't open the second, though get no icon appears.
--- Update ---
I tried it and it shows the icons and recognises when another system tray is already in use through message though also allows multiple icons to appear which is strange.
Do you have a solution now? It works for me. First execution puts icon in tray. Next executions print already in use message.
If you don't understand my answer, don't ignore it, ask a question.
No, I'll stick with file method.
Have you tried the file method across reboots of the system? Can the file be left when the system reboots?
If you don't understand my answer, don't ignore it, ask a question.
Oh I get you, my file method only works if the user gracefully exits. Is there some sort of method which I can force before the exit so I can delete the file once again upon a forceful exit by the user.
Look at the Runtime class's addShutdownHook() method.
If you don't understand my answer, don't ignore it, ask a question.
keepStriving (December 13th, 2013)
I've tried it though I get an illegal state exception though the program continues running, this is how I implemented it.
import java.awt.AWTException; import java.awt.Image; 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.io.*; import java.net.*; public class SystemTrayPostItNotes{ public static void main(String[]args)throws Exception{ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){ public void run(){ final File file = new File("C:\\Users\\HASEEB\\Desktop\\On.txt"); if(!file.exists()){ try { file.createNewFile(); } catch (IOException e) { } PopupMenu popUp = new PopupMenu(); MenuItem exit = new MenuItem("Exit"); popUp.add(exit); Image image = Toolkit.getDefaultToolkit().getImage("C:\\Users\\HASEEB\\Desktop\\GeoGebra_icon_edit.png"); TrayIcon trayIcon = new TrayIcon(image, "Post It Notes Program", popUp); try { SystemTray.getSystemTray().add(trayIcon); } catch (AWTException e) { // TODO Auto-generated catch block e.printStackTrace(); } trayIcon.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ MainGuiNotes notes = new MainGuiNotes(); } }); exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ file.delete(); /* try { clientSocket.close(); socket.close(); }catch (IOException e) { System.out.println("Can't close"); }*/ System.exit(0); } }); //System.out.println("zzzzzzzzzz"); }else{ } // }else{ // System.out.println("Already open"); //} } })); } }
Please copy the full text of the error message and paste it here. It has important info about the error.I get an illegal state exception
If you don't understand my answer, don't ignore it, ask a question.
Two things:
1) your shutdown hook creates the file. But conceptually, the application should create the file at start and then, at shutdown, remove the file.
2) (this is most important) your code is a mess for indentation, etc... but I see that the run() of the shutdown hook contains all the creation of PopupMenu, MenuItem, etc.. This is wrong.
Andrea, www.andbin.net — SCJP 5 (91%) – SCWCD 5 (94%)
Useful links for Java beginners – My new project Java Examples on Google Code
keepStriving (December 14th, 2013)
I have moved what you mentioned from run method though file does not delete upon forceful exit of program though recognises to shut program if another program is already running. Also icon still not appearing.Thank you for your help so far.
public static void main(String[]args)throws Exception{ final File file = new File("C:\\Users\\HASEEB\\Desktop\\On.txt"); final PopupMenu popUp = new PopupMenu(); final MenuItem exit = new MenuItem("Exit"); popUp.add(exit); Image image = Toolkit.getDefaultToolkit().getImage("C:\\Users\\HASEEB\\Desktop\\GeoGebra_icon_edit.png"); final TrayIcon trayIcon = new TrayIcon(image, "Post It Notes Program", popUp); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){ public void run(){ if(!file.exists()){ try { file.createNewFile(); } catch (IOException e) { } /* */ try { SystemTray.getSystemTray().add(trayIcon); } catch (AWTException e) { } trayIcon.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ MainGuiNotes notes = new MainGuiNotes(); } }); exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ file.delete(); System.exit(0); } }); }else{ } } })); } }
But ... did you understand what is a "shutdown hook"? It's a piece of code (the code in run() of Runnable instance encapsulated in Thread, passed to addShutdownHook) that gets executed only when the JVM is very close to process termination (and after the System.exit(0)).
And when the JVM terminates, do you think that this "lock" file you use is to be created ... or deleted?
Andrea, www.andbin.net — SCJP 5 (91%) – SCWCD 5 (94%)
Useful links for Java beginners – My new project Java Examples on Google Code
I still can't get the display, though also get mixed results with the file still not being deleted. I have changed the code from my last attempt. The program does not stop and keeps running.
public class SystemTrayPostItNotes{ final static File file = new File("C:\\Users\\HASEEB\\Desktop\\On.txt"); final static PopupMenu popUp = new PopupMenu(); final static MenuItem exit = new MenuItem("Exit"); static TrayIcon trayIcon = null; public static void main(String[]args)throws Exception{ popUp.add(exit); Image image = Toolkit.getDefaultToolkit().getImage("C:\\Users\\HASEEB\\Desktop\\GeoGebra_icon_edit.png"); trayIcon = new TrayIcon(image, "Post It Notes Program", popUp); SystemTrayPostItNotes tray = new SystemTrayPostItNotes(); tray.addShutdownHook(file); if(file.exists()){ file.delete(); System.out.println("File deleted"); }else{ System.out.println("file does not exist"); } } public static void addShutdownHook(final File file){ Runtime.getRuntime().addShutdownHook(new Thread(){ public void run(){ if(!file.exists()){ try { file.createNewFile(); } catch (IOException e) { } try { SystemTray.getSystemTray().add(trayIcon); } catch (AWTException e) { } trayIcon.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ MainGuiNotes notes = new MainGuiNotes(); } }); exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ System.exit(0); } }); }else{ System.out.println("File already exists therefore program already running"); } } }); } }
Sorry, but you have not yet understood the concept.
<start of your application>
Does the "lock" file exist?
Yes ----> Quit immediately (eventually, tell the user that there is another instance open)
No ----> a) Create the lock file, b) Register a shutdown hook, its run() simply has to delete the lock file, c) continue normally with the rest of your application.
Andrea, www.andbin.net — SCJP 5 (91%) – SCWCD 5 (94%)
Useful links for Java beginners – My new project Java Examples on Google Code
keepStriving (December 17th, 2013)
Turn out shutdown hook does not work for forceful exits, though I managed to get it to work for graceful exits ad understand it now.
I have managed to do the task with sockets here is the code, thanks guys.
public class SystemTrayPostItNotes extends Thread{ static File file = new File("C:\\Users\\HASEEB\\Desktop\\On.txt"); public static void main(String[]args)throws Exception{ try{ connectSocket(); sysTrayCreator(); }catch(Exception except){ System.out.println("Sorry busy"); System.exit(0); } } public static void sysTrayCreator(){ try{ PopupMenu popUp = new PopupMenu(); MenuItem exit = new MenuItem("Exit"); popUp.add(exit); Image image = Toolkit.getDefaultToolkit().getImage("C:\\Users\\HASEEB\\Desktop\\GeoGebra_icon_edit.png"); TrayIcon trayIcon = new TrayIcon(image, "Post It Notes Program", popUp); SystemTrayPostItNotes tray = new SystemTrayPostItNotes(); SystemTray.getSystemTray().add(trayIcon); trayIcon.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ MainGuiNotes notes = new MainGuiNotes(); } }); exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ System.exit(0); } }); }catch(Exception except){ System.out.println("Sorry currently busy"); } } public static void connectSocket()throws Exception{ ServerSocket serverSock = new ServerSocket(9090); Socket socket = serverSock.accept(); } }
--- Update ---
I got a small error due to synchronization though amended this with Thread.sleep(1000), though for some reason this causes two system tray icons upon first time running but only for a second after which only one is left. My final code.
public class SystemTrayPostItNotes implements Runnable{ static File file = new File("C:\\Users\\HASEEB\\Desktop\\On.txt"); public static void main(String[]args)throws Exception{ (new Thread(new SystemTrayPostItNotes())).start(); } public void run(){ try{ sysTrayCreator(); connectSocket(); }catch(Exception except){ System.out.println("Sorry busy"); System.exit(0); } } public static void sysTrayCreator()throws Exception{ Thread.sleep(1000); try{ PopupMenu popUp = new PopupMenu(); MenuItem exit = new MenuItem("Exit"); popUp.add(exit); Image image = Toolkit.getDefaultToolkit().getImage("C:\\Users\\HASEEB\\Desktop\\GeoGebra_icon_edit.png"); TrayIcon trayIcon = new TrayIcon(image, "Post It Notes Program", popUp); SystemTrayPostItNotes tray = new SystemTrayPostItNotes(); SystemTray.getSystemTray().add(trayIcon); trayIcon.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ MainGuiNotes notes = new MainGuiNotes(); } }); exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ System.exit(0); } }); }catch(Exception except){ System.out.println("Sorry currently busy"); } } public static void connectSocket()throws Exception{ ServerSocket serverSock = new ServerSocket(9090); Socket socket = serverSock.accept(); } }
But the accept() is "blocking" ...
Andrea, www.andbin.net — SCJP 5 (91%) – SCWCD 5 (94%)
Useful links for Java beginners – My new project Java Examples on Google Code
Which is why I used multithreading. It seems to work or am I going wrong somewhere again?
In your first code, you have invoked connectSocket() as first thing but accept, beeing blocking, is the problem.
In the second updated code, yes you have created a new thread but it's not very useful (it's useless) because you execute all things in that thread exactly as you did in the "main" thread for the first code. What changes is that now you invoke sysTrayCreator() as first thing and it's conceptually wrong, since you check the "lock" only after this.
Andrea, www.andbin.net — SCJP 5 (91%) – SCWCD 5 (94%)
Useful links for Java beginners – My new project Java Examples on Google Code
In second code:
The new thread and run method is meant to allow multithreading which it does as I can do sysTrayCreator() and connectSocket() though I slow down sysTrayCreator() so exception can be thrown if not accepting. It does allow multithreading as I can see icon being created alongside socket connecting.
I'm still not sure what you are trying to say?
There is no need for another thread. The ServerSocket is all that is needed to test for another program using the port. Remove the accept() call.
If you don't understand my answer, don't ignore it, ask a question.
keepStriving (December 17th, 2013)