Java JFrame删除任务栏图标
我有一个JFrame,我使用以下方法将其最小化到托盘: 这是为了显示:Java JFrame删除任务栏图标,java,swing,Java,Swing,我有一个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.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的情况下删除框架的任务栏图标
原因是,当我最小化我的应用程序时,我可以向它发送命令并执行它们,但当我将其可见性设置为false时,它就会停止执行来自外部应用程序的任何命令。我所需要做的就是在最小化时从任务栏中删除图标,并在正常时显示图标
有什么想法吗?唉好久没有回复了,看来不错。。我决定使用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):
#包括
#包括
#包括“jni.h”
#如果已定义_WIN32 | |已定义_WIN64
外部“C”
{
常量GUID CLSID_TaskbarList={0x56FDF344,0xFD6D,0x11D0,{0x95,0x8A,0x00,0x60,0x97,0xC9,0xA0,0x90};
常量GUID IID_ITaskbarList={0x56FDF342、0xFD6D、0x11D0、{0x95、0x8A、0x00、0x60、0x97、0xC9、0xA0、0x90};
常量GUID IID_ITaskbarList2={0x602D4995、0xB13A、0x429b、{0xA6、0x6E、0x19、0x35、0xE4、0x4F、0x43、0x17};
常量GUID IID_ITaskList3={0xEA1AFB91、0x9E28、0x4B86、{0x90、0xE9、0x9E、0x9F、0x8A、0x5E、0xEF、0xAF};
}
#恩迪夫
外部“C”JNIEXPORT void JNICALL Java_apptotray_apptotray_addToTaskBar(JNIEnv*,jclass,jlong WindowHandle)
{
#如果已定义_WIN32 | |已定义_WIN64
ITaskbarList*任务列表PTR;
共同初始化(nullptr);
long Result=!CoCreateInstance(CLSID_TaskbarList、nullptr、CLSCTX_SERVER、IID_ITaskbarList、reinterpret_cast(&TaskListPtr));
if(结果)TaskListPtr->AddTab(重新解释强制转换(WindowHandle));
TaskListPtr->Release();
coninitialize();
#恩迪夫
}
extern“C”JNIEXPORT void JNICALL Java_apptotray_apptotray_removeFromTaskBar(JNIEnv*,jclass,jlong WindowHandle)
{
#如果已定义_WIN32 | |已定义_WIN64
ITaskbarList*任务列表PTR;
共同初始化(nullptr);
long Result=!CoCreateInstance(CLSID_TaskbarList、nullptr、CLSCTX_SERVER、IID_ITaskbarList、reinterpret_cast(&TaskListPtr));
如果(结果)TaskListPtr->DeleteTab(重新解释强制转换(WindowHandle));
TaskListPtr->Release();
coninitialize();
#恩迪夫
}
外部“C”bool_uustdcall DllMain(HINSTANCE hinstDLL,DWORD FDFREASON,LPVOID LPV保留)
{
开关(FDSON)
{
案例DLL\u进程\u附加:
//附加到进程
//返回FALSE以使DLL加载失败
打破
案例DLL\u进程\u分离:
//从进程中分离
打破
案例DLL\u线程\u连接:
//附在螺纹上
打破
案例DLL\u线程\u分离:
//从螺纹上拆下
打破
}
返回TRUE;//成功
}
使用以下命令编译DLL:
x86_64-w64-mingw32-g++.exe-O2-Wall-DBUILD_DLL-std=c++11-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-libgcc-static libstdc++-lole32-lshell32
或者只是使用代码块来完成
如果其他人有更好的想法,请随意添加或评论或其他任何内容。。我仍然不敢相信我必须使用C++/JNI和反射来实现这一点。。荒唐的现在是2013年,Java需要加入这个程序。我知道现在已经很晚了,但我花了一个小时试图自己解决这个问题。您所要做的就是将JFrame更改为JWindow,您就完成了。我有一个相当复杂的JFrame,我只需要删除
setUndercorated()
和setDefaultCloseOperation()
。其他的一切都很好。这篇关于如何做的帖子,看起来就像你所说的,或者我应该说可能是该线程的重复?:-)否,因为它使用setVisible(false);第二个答案是等价的。我所要做的就是随意从任务栏上删除图标,然后再随意添加回来。我放弃了。。我不敢相信这样的事情在Java中会如此困难。。太可笑了。。这就是C++和java之间的区别。如果不是一堆需要处理的代码,你可以提供一个完整的解决方法,一个小的示例程序+尽管如此,双方的努力都是一样的。。添加了一个工作示例。我使用代码块编译dll。它是一个名为main.cpp的文件,java应用程序也是一个文件。从这里开始,将其添加到系统托盘与OP中的操作相同,只是不需要将框架设置为不可见。。只需将其最小化,添加任务栏图标并从任务栏中调用removeFromTaskbar。
#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
}