162 lines
4.4 KiB
Java
162 lines
4.4 KiB
Java
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);
|
|
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
|
|
* @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);
|
|
}
|
|
});
|
|
}
|
|
} |