Java 中的 Windows 7 任务栏进度条
Posted
技术标签:
【中文标题】Java 中的 Windows 7 任务栏进度条【英文标题】:Windows 7 Taskbar Progress Bar in Java 【发布时间】:2011-01-11 03:24:57 【问题描述】:我想知道当文件操作正在进行时,是否可以像 Windows 资源管理器那样在任务栏上显示进度条?
我看到很多例子,但都涉及到 C#。
SWT 不会削减它。
【问题讨论】:
你可以为那些没有Windows的人发布截图吗? 你想让它像浏览器进度条吗?还是您希望它显示在任务栏上。 (提示,这两件事中的一件比另一件困难得多)。 你是如何解决这个问题的?有什么进展吗? 【参考方案1】:由于 Java9 的 java.awt.Taskbar 仅适用于旧的摇摆框架(他们不知何故忘记为 javafx.stage.Stage 实现此功能)并且 com.nativelibs4java bridj 不再工作(请参阅https://github.com/nativelibs4java/BridJ/issues/94)我实现了使用 JNA 4.1.0 的解决方案。
请注意:
依赖于调用内部 javafx api (com.sun.javafx.stage.WindowHelper) - 所以它可能会在下一次 java 更新时中断 它仅设置“不确定”进度状态 - 但通过一些调整也应该可以实现正常进度状态希望这会有所帮助。
ITaskbarList3.java
package example;
import com.sun.jna.platform.win32.Guid.IID;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HRESULT;
public interface ITaskbarList3
IID IID_ITASKBARLIST3 = new IID("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf"); // from ShObjIdl.h
int TBPF_NOPROGRESS = 0;
int TBPF_INDETERMINATE = 0x1;
int TBPF_NORMAL = 0x2;
int TBPF_ERROR = 0x4;
int TBPF_PAUSED = 0x8;
HRESULT SetProgressState(HWND hwnd, int tbpFlags);
TaskbarList3.java
package example;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.platform.win32.COM.COMInvoker;
public final class TaskbarList3 extends COMInvoker implements ITaskbarList3
public TaskbarList3(Pointer pointer)
setPointer(pointer);
@Override
public HRESULT SetProgressState(HWND hwnd, int tbpFlags)
return (HRESULT) this._invokeNativeObject(
10, // magic number (gathered by trial and error)
new Object[] this.getPointer(), hwnd, tbpFlags ,
HRESULT.class);
TaskbarPeer.java
package example;
import com.sun.javafx.stage.WindowHelper;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Guid.CLSID;
import com.sun.jna.platform.win32.Ole32;
import com.sun.jna.platform.win32.W32Errors;
import com.sun.jna.platform.win32.WTypes;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.ptr.PointerByReference;
import javafx.stage.Stage;
public final class TaskbarPeer
public static void setIndeterminateProgress(Stage stage, boolean indeterminate)
final var peer = WindowHelper.getPeer(stage);
final long windowHandle = peer.getRawHandle();
final var clsid = new CLSID("56FDF344-FD6D-11d0-958A-006097C9A090"); // from ShObjIdl.h
final var taskbarListPointerRef = new PointerByReference();
var hr = Ole32.INSTANCE.CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER,
ITaskbarList3.IID_ITASKBARLIST3, taskbarListPointerRef);
if (W32Errors.FAILED(hr))
throw new RuntimeException("failed with code: " + hr.intValue());
final TaskbarList3 taskbarList = new TaskbarList3(taskbarListPointerRef.getValue());
final var hwnd = new HWND(new Pointer(windowHandle));
final int progressState = indeterminate ? ITaskbarList3.TBPF_INDETERMINATE : ITaskbarList3.TBPF_NOPROGRESS;
hr = taskbarList.SetProgressState(hwnd, progressState);
if (W32Errors.FAILED(hr))
throw new RuntimeException("failed with code: " + hr.intValue());
Sample.java
package example;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public final class Sample extends Application
private boolean indeterminateProgressState = false;
public static void main(String[] args)
launch(args);
@Override
public void start(Stage primaryStage) throws Exception
final Button btn = new Button("Click me!");
primaryStage.setScene(new Scene(btn));
primaryStage.sizeToScene();
primaryStage.show();
btn.setOnAction(evt ->
indeterminateProgressState = !indeterminateProgressState;
TaskbarPeer.setIndeterminateProgress(primaryStage, indeterminateProgressState);
);
【讨论】:
【参考方案2】:我发现 Java 9 中包含此功能。它是 AWT 的一部分,使用起来也非常简单。
这是一个简短的例子:
import java.awt.Taskbar;
import java.awt.Taskbar.State;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
/**
* @author fxl
*/
public class TaskbarSample
public static void main(String[] args)
// JavaDoc:
// https://docs.oracle.com/javase/9/docs/api/java/awt/Taskbar.html
// MSDNDoc:
// https://msdn.microsoft.com/en-us/library/dd391692(VS.85).aspx
if (Taskbar.isTaskbarSupported() == false)
return;
JFrame dialog = new JFrame("Test - 50%");
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
Taskbar taskbar = Taskbar.getTaskbar();
taskbar.setWindowProgressState(dialog, State.ERROR);
taskbar.setWindowProgressValue(dialog, 50);
【讨论】:
【参考方案3】:This 示例将完成这项工作:
任务栏:
代码:
import org.bridj.Platform;
import org.bridj.Pointer;
import org.bridj.cpp.com.COMRuntime;
import org.bridj.cpp.com.shell.ITaskbarList3;
import org.bridj.jawt.JAWTUtils;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TaskBarListDemo extends JFrame implements ActionListener, ChangeListener
private ITaskbarList3 list;
private JSlider slider;
private Pointer<?> hwnd;
private TaskBarListDemo() throws ClassNotFoundException
super("TaskbarList Demo (" + (Platform.is64Bits() ? "64 bits" : "32 bits") + ")");
list = COMRuntime.newInstance(ITaskbarList3.class);
getContentPane().add("Center", new JLabel("Hello Native Windows 7 World !"));
Box box = Box.createVerticalBox();
int min = 0;
int max = 300;
int val = (min + max / 2);
slider = new JSlider(min, max, val);
slider.addChangeListener(this);
box.add(slider);
ButtonGroup group = new ButtonGroup();
for (ITaskbarList3.TbpFlag state : ITaskbarList3.TbpFlag.values())
JRadioButton cb = new JRadioButton(state.name());
group.add(cb);
cb.putClientProperty(ITaskbarList3.TbpFlag.class, state);
cb.setSelected(state == ITaskbarList3.TbpFlag.TBPF_NORMAL);
cb.addActionListener(this);
box.add(cb);
getContentPane().add("South", box);
@Override
protected void finalize() throws Throwable
super.finalize();
list.Release();
public void setVisible(boolean visible)
super.setVisible(visible);
long hwndVal = JAWTUtils.getNativePeerHandle(this);
hwnd = Pointer.pointerToAddress(hwndVal);
list.SetProgressValue((Pointer) hwnd, slider.getValue(), slider.getMaximum());
@Override
public void stateChanged(ChangeEvent actionEvent)
list.SetProgressValue((Pointer) hwnd, slider.getValue(), slider.getMaximum());
@Override
public void actionPerformed(ActionEvent actionEvent)
JRadioButton button = ((JRadioButton) actionEvent.getSource());
if (button.isSelected())
ITaskbarList3.TbpFlag flag = (ITaskbarList3.TbpFlag) button.getClientProperty(ITaskbarList3.TbpFlag.class);
list.SetProgressValue((Pointer) hwnd, slider.getValue(), slider.getMaximum());
list.SetProgressState((Pointer) hwnd, flag);
public static void main(String[] arguments) throws Exception
TaskBarListDemo f = new TaskBarListDemo();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
Maven
依赖:
<dependencies>
<dependency>
<groupId>com.nativelibs4java</groupId>
<artifactId>bridj</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>LATEST</version>
</dependency>
</dependencies>
【讨论】:
只要你最上面的窗口是一个 JFrame,它就可以工作。但是 JDialog 不起作用。【参考方案4】:现在可以使用 SWT,请查看代码示例:org.eclipse.swt.snippets.Snippet336
【讨论】:
【参考方案5】:Windows 通过 COM 公开这一点。我相信“平面 DLL”调用对你来说会更容易,但如果你可以访问 COM,你就可以做到这一点。 COM 接口是 ITaskbarList3(还有一个您可以使用的 ITaskbarList4,它继承自它。)http://msdn.microsoft.com/en-us/library/dd391692(VS.85).aspx 记录了它。 SetProgressState 和 SetProgressValue 是您要调用的方法。状态为正常(绿色)、暂停(黄色)、错误(红色)、不确定(绿色闪烁)和无。在 MSDN 页面上,一些社区人员添加了从 VB 和 C# 调用此 COM 组件的详细信息 - 这可能有助于您了解 Java 所需的设置和拆卸。
【讨论】:
好的,所以我已经安装了javax.comm,但是文档很差。你有什么可以提供的吗? 抱歉,我的 Java 时代已经过去很久了,如果我知道如何从 Java 调用 COM 方法,我已经忘记了。如果您需要有关将什么传递给这些方法的文档,当然,我有调用它们的 C# 代码,所以我知道参数是什么。问吧。 nativelibs4java 似乎使用 COM【参考方案6】:Java 中还没有标准的工具可以做到这一点。
因此,您需要直接与 Windows 对话才能做到这一点。因此,您需要找到正确的 Windows 例程,并使用 JNA(可能是最简单的)来调用该例程。我不知道有哪个供应商或项目已经这样做了。
编辑:看来http://code.google.com/p/nativelibs4java/ 项目可能会做你想做的事。
【讨论】:
不,JNA比JNI好用。 BridJ(一个 NativeLibs4Java 子项目:code.google.com/p/bridj)确实提供了围绕 ITaskbarList3 的即用型包装器,以及一个工作示例:code.google.com/p/nativelibs4java/source/browse/trunk/libraries/… 演示链接好像移到了code.google.com/p/nativelibs4java/source/browse/trunk/libraries/… 呵呵,为了记录,demo 更进一步(到 github):github.com/ochafik/nativelibs4java/blob/master/libraries/… 然后……再一次? >_github.com/nativelibs4java/BridJ/blob/master/src/main/demos/…以上是关于Java 中的 Windows 7 任务栏进度条的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Windows 7 编写进度条以在任务栏上进行自我更新?
如何在 Windows 7 任务栏中显示进度(使用 Qt)?
全屏时Windows7的任务栏把视频的进度条挡住了,好烦啊,求解