Files
WebClient/src/main/java/org/openautonomousconnection/webclient/ui/TabView.java

162 lines
4.4 KiB
Java
Raw Normal View History

package org.openautonomousconnection.webclient.ui;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebHistory;
import javafx.scene.web.WebView;
import org.openautonomousconnection.oacswing.component.OACPanel;
import org.openautonomousconnection.webclient.lua.WebLogger;
import org.openautonomousconnection.webclient.settings.FxEngine;
import java.awt.*;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
/**
* A Swing panel that embeds a JavaFX WebView and runs LuaScript (no JavaScript).
*
* <p>Loads "web://" URLs so JavaFX can request subresources (CSS, images, href navigations)
* through URLConnection (mapped to OAC WebRequestPacket).</p>
*/
public final class TabView extends OACPanel {
private final AtomicBoolean initialized = new AtomicBoolean(false);
2026-02-11 23:31:49 +01:00
private final Consumer<String> onLocationChanged;
private final WebLogger webLogger;
private JFXPanel fxPanel;
private WebView webView;
private WebEngine engine;
private volatile FxEngine luaEngine;
/**
* Creates a new tab view.
*
* @param onLocationChanged callback invoked when the WebEngine location changes
2026-02-11 23:31:49 +01:00
* @param url callback invoked on URL changes
*/
public TabView(Consumer<String> onLocationChanged, String url) {
super();
this.onLocationChanged = Objects.requireNonNull(onLocationChanged, "onLocationChanged");
this.webLogger = new WebLogger(url);
setLayout(new BorderLayout());
}
@Override
public void addNotify() {
super.addNotify();
if (!initialized.compareAndSet(false, true)) {
return;
}
fxPanel = new JFXPanel();
add(fxPanel, BorderLayout.CENTER);
Platform.runLater(() -> {
webView = new WebView();
webView.setContextMenuEnabled(false);
engine = webView.getEngine();
engine.setJavaScriptEnabled(false);
engine.locationProperty().addListener((obs, oldV, newV) -> {
if (newV != null) {
onLocationChanged.accept(newV);
}
});
// Proper Lua integration from your library
luaEngine = new FxEngine(engine, webView, webLogger);
luaEngine.install();
fxPanel.setScene(new Scene(webView));
});
}
/**
* Loads a normalized URL (expected: web://...).
*
* @param url URL to load
*/
public void loadUrl(String url) {
String u = Objects.requireNonNull(url, "url").trim();
if (u.isEmpty()) return;
Platform.runLater(() -> {
if (engine != null) {
engine.load(u);
}
});
}
/**
* Reloads the current page.
*/
public void reload() {
Platform.runLater(() -> {
if (engine != null) engine.reload();
});
}
/**
* Navigates one step back in history if possible.
*/
public void back() {
Platform.runLater(() -> {
if (engine == null) return;
WebHistory h = engine.getHistory();
if (h.getCurrentIndex() > 0) h.go(-1);
});
}
/**
* Navigates one step forward in history if possible.
*/
public void forward() {
Platform.runLater(() -> {
if (engine == null) return;
WebHistory h = engine.getHistory();
if (h.getCurrentIndex() < h.getEntries().size() - 1) h.go(1);
});
}
/**
* Returns current engine location.
*
* @return location or null
*/
public String getEngineLocation() {
return engine != null ? engine.getLocation() : null;
}
/**
* Disposes resources.
*/
public void dispose() {
FxEngine le = luaEngine;
luaEngine = null;
if (le != null) {
try {
le.close();
} catch (Exception ignored) {
}
}
Platform.runLater(() -> {
if (engine != null) {
try {
engine.load(null);
} catch (Exception ignored) {
}
}
engine = null;
webView = null;
if (fxPanel != null) {
fxPanel.setScene(null);
}
});
}
}