|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|