Das Ziel meines Projekts besteht darin, in der Taskleiste den Fortschritt einer lang andauernden Aufgabe zu melden. Soweit ich weiß, gibt es in JavaFX dafür keine „native“ Unterstützung. Es gibt einige Bibliotheken wie
FXTaskbarProgressBar, die diesen Zweck erfüllen, jedoch nur für Windows-Betriebssysteme. Und es nutzt das „alte“ Java Native Interface (JNI).
Nach einer kurzen Recherche habe ich eine einfache Go-Bibliothek
Taskleiste gefunden. Diese Bibliothek hat mich dazu inspiriert, die Portierung auf Java für JavaFX auszuprobieren.
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