How to Hide a Jframe in System Tray of Taskbar

How to hide a JFrame in system tray of taskbar

import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.UIManager;

/**
*
* @author Mohammad Faisal
* ermohammadfaisal.blogspot.com
* facebook.com/m.faisal6621
*
*/

public class HideToSystemTray extends JFrame{
TrayIcon trayIcon;
SystemTray tray;
HideToSystemTray(){
super("SystemTray test");
System.out.println("creating instance");
try{
System.out.println("setting look and feel");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(Exception e){
System.out.println("Unable to set LookAndFeel");
}
if(SystemTray.isSupported()){
System.out.println("system tray supported");
tray=SystemTray.getSystemTray();

Image image=Toolkit.getDefaultToolkit().getImage("/media/faisal/DukeImg/Duke256.png");
ActionListener exitListener=new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Exiting....");
System.exit(0);
}
};
PopupMenu popup=new PopupMenu();
MenuItem defaultItem=new MenuItem("Exit");
defaultItem.addActionListener(exitListener);
popup.add(defaultItem);
defaultItem=new MenuItem("Open");
defaultItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(true);
setExtendedState(JFrame.NORMAL);
}
});
popup.add(defaultItem);
trayIcon=new TrayIcon(image, "SystemTray Demo", popup);
trayIcon.setImageAutoSize(true);
}else{
System.out.println("system tray not supported");
}
addWindowStateListener(new WindowStateListener() {
public void windowStateChanged(WindowEvent e) {
if(e.getNewState()==ICONIFIED){
try {
tray.add(trayIcon);
setVisible(false);
System.out.println("added to SystemTray");
} catch (AWTException ex) {
System.out.println("unable to add to tray");
}
}
if(e.getNewState()==7){
try{
tray.add(trayIcon);
setVisible(false);
System.out.println("added to SystemTray");
}catch(AWTException ex){
System.out.println("unable to add to system tray");
}
}
if(e.getNewState()==MAXIMIZED_BOTH){
tray.remove(trayIcon);
setVisible(true);
System.out.println("Tray icon removed");
}
if(e.getNewState()==NORMAL){
tray.remove(trayIcon);
setVisible(true);
System.out.println("Tray icon removed");
}
}
});
setIconImage(Toolkit.getDefaultToolkit().getImage("Duke256.png"));

setVisible(true);
setSize(300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
new HideToSystemTray();
}
}

This is the working program!

Java. Minimize to system tray

you can use

frame.setExtendedState(JFrame.ICONIFIED);

JFrame remove taskbar Icon

sigh well seeing as there have been no replies for quite some time.. I decided to solve it using C++/JNI, and reflection as follows:

On the Java side:

package apptotray;

import java.awt.*;
import java.io.File;
import java.nio.file.Paths;
import javax.swing.*;

public class AppToTray {

public static void main(String[] args) {
JFrame frame = new JFrame("Some Window");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JPanel(), BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(500, 500));
frame.pack();
frame.setVisible(true);

System.load(new File("JNI.dll").getAbsolutePath());
try {
System.out.println("Icon is showing..");
Thread.sleep(3000);
} catch (Exception Ex) {
Ex.printStackTrace();
}

removeFromTaskBar(getWindowHandle(frame));

try {
System.out.println("Icon is not showing..");
Thread.sleep(3000);
} catch (Exception Ex) {
Ex.printStackTrace();
}

addToTaskBar(getWindowHandle(frame));
System.out.println("Icon is showing again..");
}

public static native void addToTaskBar(long WindowHandle);

public static native void removeFromTaskBar(long WindowHandle);

public static long getWindowHandle(java.awt.Frame frame) {
return (Long)invokeMethod(invokeMethod(frame, "getPeer"), "getHWnd");
}

protected static Object invokeMethod(Object o, String methodName) {
Class c = o.getClass();
for (java.lang.reflect.Method m : c.getMethods()) {
if (m.getName().equals(methodName)) {
try {
return m.invoke(o);
} catch (IllegalAccessException | IllegalArgumentException | java.lang.reflect.InvocationTargetException Ex) {
Ex.printStackTrace();
break;
}
}
}
return null;
}
}

On the JNI/C++ side (Main.cpp):

#include <windows.h>
#include <shobjidl.h>
#include "jni.h"

#if defined _WIN32 || defined _WIN64
extern "C"
{
const GUID CLSID_TaskbarList = {0x56FDF344, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};

const GUID IID_ITaskbarList = {0x56FDF342, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};

const GUID IID_ITaskbarList2 = {0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}};

const GUID IID_ITaskList3 = {0xEA1AFB91, 0x9E28, 0x4B86, {0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF}};
}
#endif

extern "C" JNIEXPORT void JNICALL Java_apptotray_AppToTray_addToTaskBar(JNIEnv *, jclass, jlong WindowHandle)
{
#if defined _WIN32 || defined _WIN64
ITaskbarList* TaskListPtr;
CoInitialize(nullptr);
long Result = !CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_SERVER, IID_ITaskbarList, reinterpret_cast<void**>(&TaskListPtr));
if (Result) TaskListPtr->AddTab(reinterpret_cast<HWND>(WindowHandle));
TaskListPtr->Release();
CoUninitialize();
#endif
}

extern "C" JNIEXPORT void JNICALL Java_apptotray_AppToTray_removeFromTaskBar(JNIEnv *, jclass, jlong WindowHandle)
{
#if defined _WIN32 || defined _WIN64
ITaskbarList* TaskListPtr;
CoInitialize(nullptr);
long Result = !CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_SERVER, IID_ITaskbarList, reinterpret_cast<void**>(&TaskListPtr));
if (Result) TaskListPtr->DeleteTab(reinterpret_cast<HWND>(WindowHandle));
TaskListPtr->Release();
CoUninitialize();
#endif
}

extern "C" bool __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
// return FALSE to fail DLL load
break;

case DLL_PROCESS_DETACH:
// detach from process
break;

case DLL_THREAD_ATTACH:
// attach to thread
break;

case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}

Compile the DLL with:

x86_64-w64-mingw32-g++.exe -O2 -Wall -DBUILD_DLL -std=c++11 -c C:\Users\Brandon\Desktop\JNI\main.cpp -o obj\Release\main.o

x86_64-w64-mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libJNI.def -Wl,--out-implib=bin\Release\libJNI.a -Wl,--dll obj\Release\main.o -o bin\Release\JNI.dll -s -static -static-libgcc -static-libstdc++ -lole32 -lshell32 -luser32

Or just use codeblocks to do it.

If anyone else has better ideas, feel free to add them or comment or anything.. I still can't believe I had to use C++/JNI, and reflection to do this.. Ridiculous.. It's the year 2013, Java needs to get with the program.

Hiding my program in the System Tray in Windows

I know how to have my program's icon in the notification area, what I'd like is to hide it in the area where it is normally displayed when you minimize a window.

Then don't use the system tray.

The thing is, I'd like my program to stay open in the Status Area if the "X" is pressed on the window,

frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

How to minimize the application to system tray on close from ApplicationWindow object?

Here is how I resolved the issue after 2 days of research:

Override the close method!

public boolean close() {

final Shell grandShell = this.getShell();
grandShell.setVisible(false);

Display display = Display.getCurrent();

Tray tray = display.getSystemTray();
if(tray != null) {
TrayItem item = new TrayItem(tray, SWT.NONE);
item.setImage(ArecaImages.ICO_SMALL);
final Menu menu = new Menu(getShell(), SWT.POP_UP);
MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
menuItem.setText("Areca");
menuItem.addListener (SWT.Selection, new Listener () {
public void handleEvent (Event event) {
grandShell.setVisible(true);
}
});
item.addListener (SWT.MenuDetect, new Listener () {
public void handleEvent (Event event) {
menu.setVisible (true);
}
});

}

return true;


Related Topics



Leave a reply



Submit