Switched to JavaFX and added builtin Support

This commit is contained in:
Finn
2026-01-19 22:23:49 +01:00
parent 627e0c86e4
commit 8a20970e12
13 changed files with 1019 additions and 263 deletions

View File

@@ -0,0 +1,118 @@
package org.openautonomousconnection.luascript.fx;
import org.openautonomousconnection.luascript.fx.FxDomHost;
import org.openautonomousconnection.luascript.events.UiEventRegistry;
import org.openautonomousconnection.luascript.fx.FxThreadBridge;
import org.openautonomousconnection.luascript.hosts.EventHost;
import org.openautonomousconnection.luascript.runtime.LuaEventRouter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* EventHost implementation for JavaFX WebView using W3C DOM EventTarget listeners.
*
* <p>No JavaScript required. Events are forwarded to Lua via {@link LuaEventRouter}.</p>
*/
public final class FxEventHost implements EventHost {
private static final String GLOBAL_TARGET_ID = "__global__";
private final FxDomHost dom;
private final LuaEventRouter router;
private final ConcurrentHashMap<String, EventListener> elementListeners = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, EventListener> globalListeners = new ConcurrentHashMap<>();
/**
* Creates a new FxEventHost.
*
* @param dom fx dom host
* @param router lua router
*/
public FxEventHost(FxDomHost dom, LuaEventRouter router) {
this.dom = Objects.requireNonNull(dom, "dom");
this.router = Objects.requireNonNull(router, "router");
}
@Override
public void addListener(String elementId, String eventName) {
Objects.requireNonNull(elementId, "elementId");
Objects.requireNonNull(eventName, "eventName");
String evt = UiEventRegistry.normalize(eventName);
String key = elementId + "\n" + evt;
elementListeners.computeIfAbsent(key, k -> {
EventListener listener = ev -> {
Map<String, Object> payload = FxEventPayloadExtractor.extract(ev);
router.emit(elementId, evt, payload);
};
FxThreadBridge.runAndWait(() -> {
Element el = dom.byId(elementId);
((EventTarget) el).addEventListener(evt, listener, false);
});
return listener;
});
}
@Override
public void removeListener(String elementId, String eventName) {
Objects.requireNonNull(elementId, "elementId");
Objects.requireNonNull(eventName, "eventName");
String evt = UiEventRegistry.normalize(eventName);
String key = elementId + "\n" + evt;
EventListener listener = elementListeners.remove(key);
if (listener == null) return;
FxThreadBridge.runAndWait(() -> {
Element el = dom.byId(elementId);
((EventTarget) el).removeEventListener(evt, listener, false);
});
}
@Override
public void addGlobalListener(String eventName) {
Objects.requireNonNull(eventName, "eventName");
String evt = UiEventRegistry.normalize(eventName);
globalListeners.computeIfAbsent(evt, k -> {
EventListener listener = ev -> {
Map<String, Object> payload = FxEventPayloadExtractor.extract(ev);
router.emit(GLOBAL_TARGET_ID, evt, payload);
};
FxThreadBridge.runAndWait(() -> {
Document doc = dom.requireDocument();
((EventTarget) doc).addEventListener(evt, listener, false);
});
return listener;
});
}
@Override
public void removeGlobalListener(String eventName) {
Objects.requireNonNull(eventName, "eventName");
String evt = UiEventRegistry.normalize(eventName);
EventListener listener = globalListeners.remove(evt);
if (listener == null) return;
FxThreadBridge.runAndWait(() -> {
Document doc = dom.requireDocument();
((EventTarget) doc).removeEventListener(evt, listener, false);
});
}
}