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?
Причина в том, что когда я сворачиваю свое приложение, я могу посылать ему команды, и он выполняет их, но в ту секунду, когда я устанавливаю его видимость ложная, он перестает выполнять любые команды из внешнего приложения. Все, что мне нужно сделать, это удалить значок из панели задач, когда он свернут, и показать значок в обычном режиме.
Есть идеи?
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