изучить новый API — использовать его в проекте. Моя цель состоит в том, чтобы каким-то образом
иметь возможность отображать на панели задач ход выполнения какой-либо долго выполняемой задачи.
Насколько мне известно, в JavaFX нет «встроенной» поддержки этого.
Существуют некоторые библиотеки, такие как
"https://github.com/Dansoftowner/FXTaskbarProgressBar", которые служат
цели, но только для Windows. И он использует «старый» JNI.
После небольшого исследования я нашел простую библиотеку в go
https://github.com/bibelin/taskbar. Он был вдохновлен этой библиотекой
и попытался «конвертировать» ее в JavaFX.
Сначала я использовал jextract, чтобы получить привязки Java к вызовам собственной библиотеки:
Код: Выделить всё
jextract --output target/generated-sources/jextract -t "taskbar_test.gen" --include-function "XOpenDisplay" --include-function "XChangeProperty" --include-function "XFlush" --include-function "XCloseDisplay" /usr/include/X11/Xlib.h
где я пытаюсь обновить прогресс на панели задач, вызывая метод
"XChangeProperty", который я нашел в документации X11:
https://www.x.org/releases/X11R7.7/doc/ ... geProperty
К сожалению, это не работает. Программа не аварийно завершает работу,
задача выполняется в фоновом режиме, но никаких обновлений на панели задач не происходит.
Вот код, который я создал:
Код: Выделить всё
package taskbar_test;
import com.sun.glass.ui.Window;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import taskbar_test.gen.Xlib_h;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
public class AppLinuxXlib extends Application {
@Override
public void start(Stage primaryStage) {
Button startButton = new Button("Start Long Running Task");
startButton.setOnAction(event -> {
final long rawHandle = Window.getWindows().getFirst().getRawHandle();
System.out.println(rawHandle);
// Create a long-running task
Task longTask = new Task() {
@Override
protected Void call() throws Exception {
System.out.println("Started");
try (var arena = Arena.ofConfined()) {
var NET_WM_XAPP_PROGRESS = arena.allocateFrom("NET_WM_XAPP_PROGRESS");
// var NET_WM_XAPP_PROGRESS_PULSE = arena.allocateFrom("NET_WM_XAPP_PROGRESS_PULSE");
MemorySegment x11Session = Xlib_h.XOpenDisplay(MemorySegment.NULL);
System.out.println(x11Session);
// Prepare the progress data
MemorySegment initData = arena.allocateFrom(ValueLayout.JAVA_INT, 0);
Xlib_h.XChangeProperty(x11Session, // display
MemorySegment.ofAddress(rawHandle).address(), // window
NET_WM_XAPP_PROGRESS.address(), // property
6, // type
32, // format
0, // mode PropModeReplace=0
initData, // data
1); // nelements
Xlib_h.XFlush(x11Session);
System.out.println("Countdown started");
// Set the taskbar progress
for (int i = 0; i
Подробнее здесь: [url]https://stackoverflow.com/questions/79354536/how-to-manage-taskbar-from-javafx[/url]
Мобильная версия