die Möglichkeit zu haben, den Fortschritt einer lang laufenden Aufgabe in einer Taskleiste anzuzeigen.
Soweit ich weiß, gibt es dafür in JavaFX keine „native“ Unterstützung.
Es gibt einige Bibliotheken wie „https://github.com/Dansoftowner/FXTaskbarProgressBar“, die diesen Zweck erfüllen, jedoch nur für Windows. Und es verwendet das „alte“ JNI.
Nach einer kurzen Recherche habe ich eine einfache Bibliothek unter go
https://github.com/bibelin/taskbar gefunden. Es wurde von dieser Bibliothek inspiriert
und versuchte, sie in JavaFX zu „konvertieren“.
Zuerst habe ich Jextract verwendet, um Java-Bindungen an native Bibliotheksaufrufe zu erhalten:
Code: Select all
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
wo ich versuche, den Fortschritt in der Taskleiste zu aktualisieren, indem ich die Methode
„XChangeProperty“ aufrufe, die ich in der Dokumentation gefunden habe X11:
https://www.x.org/releases/X11R7.7/doc/ ... geProperty
Leider funktioniert das nicht. Das Programm stürzt nicht ab,
Aufgabe läuft im Hintergrund, aber es findet keine Aktualisierung in der Taskleiste statt.
Hier ist der Code, den ich erstellt habe:
Code: Select all
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