JFrame удалить значок панели задач



У меня есть JFrame, который я сворачиваю в лоток, используя:



Это для показа:



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


А это для сокрытия:



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


Однако, я не хочу, чтобы установить рамку невидимой.. Когда я устанавливаю его невидимым, он удаляет значок панели задач, который мне нравится. Есть ли способ удалить значок рамки на панели задач, не устанавливая видимость в false?



Причина в том, что когда я сворачиваю свое приложение, я могу посылать ему команды, и он выполняет их, но в ту секунду, когда я устанавливаю его видимость ложная, он перестает выполнять любые команды из внешнего приложения. Все, что мне нужно сделать, это удалить значок из панели задач, когда он свернут, и показать значок в обычном режиме.



Есть идеи?

523   2  

2 ответов:

Вздох хорошо, видя, что уже довольно давно не было никаких ответов.. Я решил решить его с помощью C++/JNI, и размышления следующим образом:

На стороне Java:

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;
    }
}

На стороне JNI/C++ (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
}

Скомпилируйте DLL с помощью:

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++.ехе -общая -Wl, -- output-def=bin\Release\libJNI.def-Wl, -- out-implib=bin \ Release\libJNI.a-Wl,--dll obj\Release\main.o-o bin \ Release\JNI.ДЛЛ -ы -статический -статический-на libgcc -статический-с libstdc++ -lole32 -lshell32 -luser32

Или просто используйте кодовые блоки для этого.

Если у кого-то есть идеи получше, не стесняйтесь добавлять их или комментировать.. Я до сих пор не могу поверить, что мне пришлось использовать C++/JNI и reflection, чтобы сделать это.. Нелепый.. Это 2013 год, Java должна получить с программой.

Я знаю, что уже очень поздно, но я потратил добрый час, пытаясь разобраться в этом самостоятельно. Все, что вам нужно сделать, это изменить ваш JFrame на JWindow, и вы закончили. У меня был довольно сложный JFrame, и единственными вещами, которые я должен был удалить, были setUndecorated() и setDefaultCloseOperation(). все остальное работало просто отлично.

Comments

    Ничего не найдено.