Browse Source

REPORT-143738 使用jxbrowser的JxUIPane组件优化卡顿

fbp/feature
vito 2 months ago
parent
commit
0177804ecc
  1. 133
      designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java

133
designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java

@ -23,16 +23,24 @@ import com.teamdev.jxbrowser.view.swing.BrowserView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fr.design.ui.ModernUIConstants.COMPONENT_TAG;
import static com.fr.design.ui.ModernUIConstants.DEFAULT_EXPRESSION;
import static com.fr.design.ui.ModernUIConstants.DEFAULT_NAMESPACE;
@ -61,33 +69,78 @@ public class JxUIPane<T> extends BasicPane {
*/
public static final String COLON = ":";
private static final String COLON_ESCAPE = "\\:";
private Browser browser;
private String namespace = "Pool";
private String variable = "data";
private String expression = "update()";
private JxEngine jxEngine = JxEngine.getInstance();
private JxUIPane() {
}
private final JxEngine jxEngine;
private Consumer<Browser> initCallback = null;
private JxUIPane(JxEngine jxEngine) {
this.jxEngine = jxEngine;
}
private void initialize() {
private void initialize(Consumer<Browser> consumer) {
setLayout(new BorderLayout());
if (browser != null) {
return;
}
hackInITInnovationLinuxDesktop();
initCallback = consumer;
initDebugIfNeeded();
browser = jxEngine.getEngine().newBrowser();
if (jxEngine.isDisableWebSecurity()) {
// 忽略证书验证,兼容有些情况下自定义证书与实际域名不匹配的情况。
// 虽然不是个正确的方式,但真有这么用的还是兼容一下
browser.set(CertificateErrorCallback.class, (params, action) -> action.allow());
JProgressBar jProgressBar = showProgressBar();
new SwingWorker<Browser, Void>() {
@Override
protected Browser doInBackground() {
browser = jxEngine.getEngine().newBrowser();
if (jxEngine.isDisableWebSecurity()) {
// 忽略证书验证,兼容有些情况下自定义证书与实际域名不匹配的情况。
// 虽然不是个正确的方式,但真有这么用的还是兼容一下
browser.set(CertificateErrorCallback.class, (params, action) -> action.allow());
}
return browser;
}
@Override
protected void done() {
jProgressBar.setVisible(false);
try {
Browser mBrowser = get();
add(BrowserView.newInstance(mBrowser), BorderLayout.CENTER);
if (initCallback != null) {
initCallback.accept(mBrowser);
}
initCallback = null;
revalidate();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
/**
* hack部分 Linux 信创桌面打开需要先初始化 Desktop
*/
private static void hackInITInnovationLinuxDesktop() {
if (OperatingSystem.isLinux()) {
Desktop.getDesktop();
}
add(BrowserView.newInstance(browser), BorderLayout.CENTER);
}
/**
* 加载组件时显示一个进度条
*/
private @NotNull JProgressBar showProgressBar() {
JProgressBar jProgressBar = new JProgressBar();
jProgressBar.setIndeterminate(true);
add(row(
flex(),
column(flex(), cell(jProgressBar), flex()),
flex()
).getComponent(), BorderLayout.CENTER);
return jProgressBar;
}
/**
@ -97,8 +150,23 @@ public class JxUIPane<T> extends BasicPane {
* @param headers 自定义头
*/
public void addXHRHeaders(Map<String, String> headers) {
if (JxEngine.getInstance() != jxEngine) {
jxEngine.addXHRHeaders(headers);
warpCallback(browser -> {
if (JxEngine.getInstance() != jxEngine) {
jxEngine.addXHRHeaders(headers);
}
});
}
/**
* 异步链式调用
*
* @param then 后续任务
*/
private void warpCallback(Consumer<Browser> then) {
if (initCallback != null) {
initCallback = initCallback.andThen(then);
} else {
then.accept(browser);
}
}
@ -161,7 +229,7 @@ public class JxUIPane<T> extends BasicPane {
* @param url 新的地址
*/
public void redirect(String url) {
browser.navigation().loadUrl(encodeWindowsPath(url));
warpCallback(browser -> browser.navigation().loadUrl(encodeWindowsPath(url)));
}
/**
@ -172,7 +240,7 @@ public class JxUIPane<T> extends BasicPane {
*/
public void redirect(String url, Map<String, String> map) {
setMap(map);
browser.navigation().loadUrl(encodeWindowsPath(url));
warpCallback(browser -> browser.navigation().loadUrl(encodeWindowsPath(url)));
}
private void setMap(Map<String, String> map) {
@ -195,19 +263,11 @@ public class JxUIPane<T> extends BasicPane {
* @param t 数据类
*/
public void populate(final T t) {
setInjectJsCallback(params -> {
warpCallback(browser -> setInjectJsCallback(params -> {
executeJsObject(params.frame(), WINDOW + DOT + namespace)
.ifPresent(ns -> ns.putProperty(variable, t));
return InjectJsCallback.Response.proceed();
});
if (browser.mainFrame().isPresent()) {
executeJavaScript(WINDOW + DOT + namespace,
(Consumer<JsObject>) jsObject -> {
if (Objects.nonNull(jsObject)) {
jsObject.putProperty(variable, t);
}
});
}
}));
}
@Nullable
@ -573,16 +633,17 @@ public class JxUIPane<T> extends BasicPane {
pane.expression = expression;
pane.setMap(parameterMap);
pane.setComponent(component);
pane.initialize();
injectJs(pane);
if (!Objects.isNull(listenerPair)) {
pane.browser.navigation().on(listenerPair.getFirst(), listenerPair.getSecond());
}
if (StringUtils.isNotEmpty(this.url)) {
pane.browser.navigation().loadUrl(encodeWindowsPath(this.url));
} else if (StringUtils.isNotEmpty(this.html)) {
pane.browser.mainFrame().ifPresent(f -> f.loadHtml(html));
}
pane.initialize(browser -> {
injectJs(pane);
if (!Objects.isNull(listenerPair)) {
browser.navigation().on(listenerPair.getFirst(), listenerPair.getSecond());
}
if (StringUtils.isNotEmpty(url)) {
browser.navigation().loadUrl(encodeWindowsPath(url));
} else if (StringUtils.isNotEmpty(html)) {
browser.mainFrame().ifPresent(f -> f.loadHtml(html));
}
});
return pane;
}

Loading…
Cancel
Save