Индикатор выполнения панели задач Windows 7 в Java - PullRequest
19 голосов
/ 30 января 2010

Я хотел бы знать, возможно ли сделать индикатор выполнения на панели задач, как это делает проводник Windows, когда происходит файловая операция?

Я видел много примеров, но все они были связаны с C #.

SWT не будет сокращать его.

progress bar displayed on the taskbar

Ответы [ 7 ]

11 голосов
/ 20 июня 2011

теперь это возможно с помощью SWT, просмотрите пример кода:
org.eclipse.swt.snippets.Snippet336

6 голосов
/ 22 декабря 2017

Я обнаружил, что эта функция включена в 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);     
    }

}
6 голосов
/ 11 марта 2016

Этот пример сделает работу:

Панель задач:
enter image description here

Код:

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>
5 голосов
/ 30 января 2010

В Java пока нет стандартного средства для этого.

Следовательно, вам нужно напрямую поговорить с Windows, чтобы сделать это. Поэтому вам нужно найти правильную подпрограмму Windows и использовать JNA (вероятно, самый простой) для вызова этой подпрограммы. Я не знаю ни продавца, ни проекта, который уже сделал это.


Редактировать: Похоже, что проект http://code.google.com/p/nativelibs4java/ может делать то, что вы хотите.

3 голосов
/ 02 декабря 2010

Существует библиотека Java, предоставляющая новые возможности Windows 7 для Java. Он называется J7Goodies Strix Code . Позволяет отображать индикатор на панели задач и многое другое.

0 голосов
/ 14 июля 2018

Поскольку java.awt.Taskbar в Java9 работает только для старых фреймов качания (они почему-то забыли реализовать это для 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);
}

1021 * 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);
        });
    }
}
0 голосов
/ 30 января 2010

Windows выставляет это через COM. Я уверен, что вызов "плоской DLL" будет проще для вас, но если вы можете добраться до COM, вы можете сделать это. COM-интерфейс - это ITaskbarList3 (также можно использовать ITaskbarList4, который наследуется от него.) http://msdn.microsoft.com/en-us/library/dd391692(VS.85).aspx документирует его. SetProgressState и SetProgressValue - это методы, которые вы хотите вызвать. Состояние нормальное (зеленое), приостановлено (желтое), ошибка (красное), неопределенное (свист зеленый) и нет. На странице MSDN некоторые пользователи сообщества добавили сведения о вызове этого COM-компонента из VB и C #, что может помочь вам выяснить, какие настройки и требования требуются для Java.

...