简体   繁体   中英

JFrame remove taskbar Icon

I have a JFrame that I minimize to the tray using:

This for showing:

Frame.this.Minimized = false;
Frame.this.setVisible(true);
systemTray.remove(systemTrayIcon);
Frame.this.setExtendedState(JFrame.NORMAL);

And this for hiding:

if (SystemTray.isSupported()) {
    systemTray.add(systemTrayIcon);
    Frame.this.setVisible(false);
    Frame.this.Minimized = true;
}
Frame.this.setExtendedState(JFrame.ICONIFIED);

However, I do NOT want to set the frame invisible.. When I set it invisible, it removes the taskbar icon which I like. Is there a way to remove the taskbar icon of the frame without setting the visibility to false?

The reason is because when I minimize my application, I can send it commands and it executes them but the second that I set its visibility to false, it stops executing any commands from an external application. All I need to do is remove the icon from the taskbar when minimized and show the icon when normal.

Any ideas?

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.

I know this is VERY late, but I spent a good hour trying to figure this out myself. All you have to do is change your JFrame to a JWindow and you're done. I had a fairly complex JFrame and the only things I had to remove were setUndecorated() and setDefaultCloseOperation() . everything else worked just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM