Browse Source

Pull request #4939: REPORT-55070【组件背景分离】 组件复用-tab块点击右侧添加标签按钮,没生效 && KERNEL-7634 mac和win使用不同版本的jxbrowser

Merge in DESIGN/design from ~HADES/design:feature/10.0 to feature/10.0

* commit 'f8b37438f976ed040b0d3bc153f1fba3a75cbf7f':
  KERNEL-7634 mac和win使用不同版本的jxbrowser fix 登录名获取方式
  KERNEL-7634 mac和win使用不同版本的jxbrowser
  REPORT-55070【组件背景分离】 组件复用-tab块点击右侧添加标签按钮,没生效
feature/10.0
Hades 4 years ago
parent
commit
13b1da490d
  1. 8
      build.gradle
  2. 24
      designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java
  3. 24
      designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java
  4. 20
      designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java
  5. 301
      designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java
  6. 3
      designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java
  7. 14
      designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java
  8. 502
      designer-base/src/main/java/com/fr/design/upm/NewUpmBridge.java
  9. 4
      designer-base/src/main/java/com/fr/design/upm/UpmBridge.java
  10. 3
      designer-base/src/main/java/com/fr/design/upm/UpmFinder.java
  11. 35
      designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java
  12. 30
      designer-base/src/main/java/com/fr/design/upm/exec/NewUpmBrowserExecutor.java
  13. 7
      designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java

8
build.gradle

@ -60,10 +60,10 @@ allprojects {
implementation 'com.fr.third:jxbrowser:6.23' implementation 'com.fr.third:jxbrowser:6.23'
implementation 'com.fr.third:jxbrowser-mac:6.23' implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation 'com.fr.third:jxbrowser-win64:6.23' implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation 'com.fr.third:jxbrowser-v7:7.5' implementation 'com.fr.third:jxbrowser-v7:7.7'
implementation 'com.fr.third:jxbrowser-mac-v7:7.5' implementation 'com.fr.third:jxbrowser-mac-v7:7.7'
implementation 'com.fr.third:jxbrowser-win64-v7:7.5' implementation 'com.fr.third:jxbrowser-win64-v7:7.7'
implementation 'com.fr.third:jxbrowser-swing:7.5' implementation 'com.fr.third:jxbrowser-swing-v7:7.7'
implementation 'com.fr.third.server:servlet-api:3.0' implementation 'com.fr.third.server:servlet-api:3.0'
implementation 'org.swingexplorer:swexpl:2.0.1' implementation 'org.swingexplorer:swexpl:2.0.1'
implementation 'org.swingexplorer:swag:1.0' implementation 'org.swingexplorer:swag:1.0'

24
designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java

@ -5,8 +5,10 @@ import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.compatible.BuilderDiff;
import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.web.struct.AssembleComponent; import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.Browser; import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserType; import com.teamdev.jxbrowser.chromium.BrowserType;
import com.teamdev.jxbrowser.chromium.JSValue; import com.teamdev.jxbrowser.chromium.JSValue;
@ -42,6 +44,10 @@ public class ModernUIPane<T> extends BasicPane {
initialize(browserType); initialize(browserType);
} }
protected ModernUIPane() {
}
private void initialize(BrowserType browserType) { private void initialize(BrowserType browserType) {
if (browser == null) { if (browser == null) {
setLayout(new BorderLayout()); setLayout(new BorderLayout());
@ -151,7 +157,7 @@ public class ModernUIPane<T> extends BasicPane {
return null; return null;
} }
public static class Builder<T> { public static class Builder<T> implements BuilderDiff<T> {
private ModernUIPane<T> pane; private ModernUIPane<T> pane;
@ -271,6 +277,22 @@ public class ModernUIPane<T> extends BasicPane {
return this; return this;
} }
@Override
public Builder<T> prepareForV6(ScriptContextListener contextListener) {
return prepare(contextListener);
}
@Override
public Builder<T> prepareForV6(LoadListener loadListener) {
return prepare(loadListener);
}
@Override
public Builder<T> prepareForV7(InjectJsCallback callback) {
// do nothing
return this;
}
public ModernUIPane<T> build() { public ModernUIPane<T> build() {
return pane; return pane;
} }

24
designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java

@ -0,0 +1,24 @@
package com.fr.design.ui.compatible;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
/**
* 封装jxbrwoser v6/v7的构建方式的差异
*
* @author hades
* @version 10.0
* Created by hades on 2021/6/13
*/
public interface BuilderDiff<T> {
ModernUIPane.Builder<T> prepareForV6(ScriptContextListener contextListener);
ModernUIPane.Builder<T> prepareForV6(LoadListener loadListener);
ModernUIPane.Builder<T> prepareForV7(InjectJsCallback callback);
}

20
designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java

@ -0,0 +1,20 @@
package com.fr.design.ui.compatible;
import com.fr.design.ui.ModernUIPane;
import com.fr.stable.os.OperatingSystem;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/6/13
*/
public class ModernUIPaneFactory {
public static <T> ModernUIPane.Builder<T> modernUIPaneBuilder() {
if (OperatingSystem.isWindows()) {
return new NewModernUIPane.Builder<>();
} else {
return new ModernUIPane.Builder<>();
}
}
}

301
designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java

@ -0,0 +1,301 @@
package com.fr.design.ui.compatible;
import com.fr.design.DesignerEnvManager;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIConstants;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.net.Network;
import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Map;
import java.util.Optional;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
/**
* 基于v7 jxbrowser实现
*
* @author richie
* @version 10.0
* Created by richie on 2019-03-04
* 用于加载html5的Swing容器可以在设计选项设置中打开调试窗口示例可查看com.fr.design.ui.ModernUIPaneTest
*/
public class NewModernUIPane<T> extends ModernUIPane<T> {
private Browser browser;
private String namespace = "Pool";
private String variable = "data";
private String expression = "update()";
private NewModernUIPane() {
super();
initialize();
}
private void initialize() {
setLayout(new BorderLayout());
if (browser == null) {
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
UIToolbar toolbar = new UIToolbar();
add(toolbar, BorderLayout.NORTH);
UIButton openDebugButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Open_Debug_Window"));
toolbar.add(openDebugButton);
UIButton reloadButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Reload"));
toolbar.add(reloadButton);
UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window"));
toolbar.add(closeButton);
openDebugButton.addActionListener(e -> showDebuggerDialog());
reloadButton.addActionListener(e -> browser.navigation().reloadIgnoringCache());
closeButton.addActionListener(e -> SwingUtilities.getWindowAncestor(
NewModernUIPane.this).setVisible(false));
initializeBrowser();
add(BrowserView.newInstance(browser), BorderLayout.CENTER);
} else {
initializeBrowser();
add(BrowserView.newInstance(browser), BorderLayout.CENTER);
}
}
}
private void showDebuggerDialog() {
JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this));
Engine engine = Engine.newInstance(
EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED)
.addSwitch("--disable-google-traffic")
.remoteDebuggingPort(9222).build());
Browser debugger = engine.newBrowser();
BrowserView debuggerView = BrowserView.newInstance(debugger);
dialog.add(debuggerView, BorderLayout.CENTER);
dialog.setSize(new Dimension(800, 400));
GUICoreUtils.centerWindow(dialog);
dialog.setVisible(true);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
browser.devTools().remoteDebuggingUrl().ifPresent(url -> {
debugger.navigation().loadUrl(url);
});
}
private void initializeBrowser() {
Engine engine = Engine.newInstance(EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").build());
browser = engine.newBrowser();
// 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的
browser.set(InjectJsCallback.class, params -> {
params.frame().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace));
return InjectJsCallback.Response.proceed();
});
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
*/
@Override
public void redirect(String url) {
browser.navigation().loadUrl(url);
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
* @param map 初始化参数
*/
@Override
public void redirect(String url, Map<String, String> map) {
Network network = browser.engine().network();
network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map));
browser.navigation().loadUrl(url);
}
@Override
protected String title4PopupWindow() {
return "Modern";
}
@Override
public void populate(final T t) {
browser.set(InjectJsCallback.class, params -> {
JsObject ns = params.frame().executeJavaScript("window." + namespace);
if (ns != null) {
ns.putProperty(variable, t);
}
return InjectJsCallback.Response.proceed();
});
}
@Override
public T update() {
if (browser.mainFrame().isPresent()) {
return browser.mainFrame().get().executeJavaScript("window." + namespace + "." + expression);
}
return null;
}
public static class Builder<T> extends ModernUIPane.Builder<T> {
private NewModernUIPane<T> pane = new NewModernUIPane<>();
public NewModernUIPane.Builder<T> prepare(InjectJsCallback callback) {
pane.browser.set(InjectJsCallback.class, callback);
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
@Override
public NewModernUIPane.Builder<T> withEMB(final String path) {
Network network = pane.browser.engine().network();
network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, null));
pane.browser.navigation().loadUrl("emb:" + path);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
@Override
public NewModernUIPane.Builder<T> withURL(final String url) {
Network network = pane.browser.engine().network();
network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network));
pane.browser.navigation().loadUrl(url);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
@Override
public NewModernUIPane.Builder<T> withURL(final String url, Map<String, String> map) {
Network network = pane.browser.engine().network();
network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map));
pane.browser.navigation().loadUrl(url);
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
@Override
public NewModernUIPane.Builder<T> withComponent(AssembleComponent component) {
Network network = pane.browser.engine().network();
network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component));
pane.browser.navigation().loadUrl("emb:dynamic");
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
@Override
public NewModernUIPane.Builder<T> withComponent(AssembleComponent component, Map<String, String> map) {
Network network = pane.browser.engine().network();
network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component, map));
pane.browser.navigation().loadUrl("emb:dynamic");
return this;
}
/**
* 加载html文本内容
*
* @param html 要加载html文本内容
*/
@Override
public NewModernUIPane.Builder<T> withHTML(String html) {
Network network = pane.browser.engine().network();
network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network));
pane.browser.mainFrame().ifPresent(frame -> {
frame.loadHtml(html);
});
return this;
}
/**
* 设置该前端页面做数据交换所使用的对象
*
* @param namespace 对象名
*/
@Override
public NewModernUIPane.Builder<T> namespace(String namespace) {
pane.namespace = namespace;
return this;
}
/**
* java端往js端传数据时使用的变量名字
*
* @param name 变量的名字
*/
@Override
public NewModernUIPane.Builder<T> variable(String name) {
pane.variable = name;
return this;
}
/**
* js端往java端传数据时执行的函数表达式
*
* @param expression 函数表达式
*/
@Override
public NewModernUIPane.Builder<T> expression(String expression) {
pane.expression = expression;
return this;
}
@Override
public NewModernUIPane.Builder<T> prepareForV6(ScriptContextListener contextListener) {
// do nothing
return this;
}
@Override
public NewModernUIPane.Builder<T> prepareForV6(LoadListener loadListener) {
// do nothing
return this;
}
@Override
public NewModernUIPane.Builder<T> prepareForV7(InjectJsCallback callback) {
return prepare(callback);
}
@Override
public NewModernUIPane<T> build() {
return pane;
}
}
}

3
designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java

@ -49,6 +49,9 @@ public class NxComplexInterceptRequestCallback extends NxInterceptRequestCallbac
path = path.substring(4); path = path.substring(4);
} }
InputStream inputStream = IOUtils.readResource(path); InputStream inputStream = IOUtils.readResource(path);
if (inputStream == null) {
return Response.proceed();
}
return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, getMimeType(path), IOUtils.inputStream2Bytes(inputStream))); return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, getMimeType(path), IOUtils.inputStream2Bytes(inputStream)));
} }
} }

14
designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java

@ -100,6 +100,11 @@ public class NxInterceptRequestCallback implements InterceptRequestCallback {
} }
String getMimeType(String path) { String getMimeType(String path) {
// 去除 xxx?xxx 后面部分
int index = path.indexOf("?");
if (index != -1) {
path = path.substring(0, path.indexOf("?"));
}
if (StringUtils.isBlank(path)) { if (StringUtils.isBlank(path)) {
return "text/html"; return "text/html";
} }
@ -124,6 +129,15 @@ public class NxInterceptRequestCallback implements InterceptRequestCallback {
if (path.endsWith(".gif")) { if (path.endsWith(".gif")) {
return "image/gif"; return "image/gif";
} }
if (path.endsWith(".woff")) {
return "font/woff";
}
if (path.endsWith(".ttf")) {
return "truetype";
}
if (path.endsWith(".eot")) {
return "embedded-opentype";
}
Path file = new File(path).toPath(); Path file = new File(path).toPath();
try { try {
return Files.probeContentType(file); return Files.probeContentType(file);

502
designer-base/src/main/java/com/fr/design/upm/NewUpmBridge.java

@ -0,0 +1,502 @@
package com.fr.design.upm;
import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.extra.PluginUtils;
import com.fr.design.extra.exe.GetInstalledPluginsExecutor;
import com.fr.design.extra.exe.GetPluginCategoriesExecutor;
import com.fr.design.extra.exe.GetPluginFromStoreExecutor;
import com.fr.design.extra.exe.GetPluginPrefixExecutor;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.extra.exe.ReadUpdateOnlineExecutor;
import com.fr.design.extra.exe.SearchOnlineExecutor;
import com.fr.design.i18n.Toolkit;
import com.fr.design.upm.event.CertificateEvent;
import com.fr.design.upm.event.DownloadEvent;
import com.fr.design.upm.exec.NewUpmBrowserExecutor;
import com.fr.design.upm.task.UpmTaskWorker;
import com.fr.event.EventDispatcher;
import com.fr.general.GeneralUtils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-12
* 桥接Java和JavaScript的类
*/
public class NewUpmBridge extends UpmBridge {
public static NewUpmBridge getBridge(JsObject jsObject) {
return new NewUpmBridge(jsObject);
}
private JsObject jsObject;
private NewUpmBridge(JsObject jsObject) {
this.jsObject = jsObject;
}
/**
* 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
@JsAccessible
public void update(final JsFunction callback) {
callback.invoke(jsObject, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start"));
try {
UpmResourceLoader.INSTANCE.download();
UpmResourceLoader.INSTANCE.install();
callback.invoke(jsObject, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success"));
EventDispatcher.fire(DownloadEvent.UPDATE, "success");
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
callback.invoke(jsObject, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error"));
}
}
/**
* 下载并安装插件管理中心的资源文件
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
@JsAccessible
public void startDownload(final JsFunction callback) {
callback.invoke(jsObject, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start"));
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
UpmResourceLoader.INSTANCE.download();
UpmResourceLoader.INSTANCE.install();
return null;
}
@Override
protected void done() {
try {
get();
callback.invoke(jsObject, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success"));
EventDispatcher.fire(DownloadEvent.SUCCESS, "success");
} catch (Exception e) {
callback.invoke(jsObject, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error"));
FineLoggerFactory.getLogger().error(e.getMessage(), e);
EventDispatcher.fire(DownloadEvent.ERROR, "error");
}
}
}.execute();
}
/**
* 获取upm的版本信息
*
* @return 版本信息
*/
@JSBridge
@JsAccessible
@Override
public String getVersion() {
return super.getVersion();
}
@JSBridge
@JsAccessible
@Override
public String i18nText(String key) {
return super.i18nText(key);
}
@JSBridge
@JsAccessible
@Override
public void closeWindow() {
super.closeWindow();
}
@JSBridge
@JsAccessible
@Override
public boolean isDesigner() {
return super.isDesigner();
}
@JSBridge
@JsAccessible
public void getPackInfo(final JsFunction callback) {
callback.invoke(jsObject, StringUtils.EMPTY);
}
@JSBridge
@JsAccessible
public void getPluginPrefix(final JsFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetPluginPrefixExecutor());
task.execute();
}
/**
* 在线获取插件分类
*
* @param callback 回调函数
*/
@JSBridge
@JsAccessible
public void getPluginCategories(final JsFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetPluginCategoriesExecutor());
task.execute();
}
/**
* 根据条件获取在线插件
*
* @param info 插件信息
* @param callback 回调函数
*/
@JSBridge
@JsAccessible
public void getPluginFromStoreNew(String info, final JsFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetPluginFromStoreExecutor(new JSONObject(info)));
task.execute();
}
/**
* 已安装插件检查更新
*/
@JSBridge
@JsAccessible
public void readUpdateOnline(final JsFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new ReadUpdateOnlineExecutor());
task.execute();
}
/**
* 获取已经安装的插件的数组
*/
@JSBridge
@JsAccessible
public void getInstalledPlugins(final JsFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetInstalledPluginsExecutor());
task.execute();
}
/**
* 从插件服务器上更新选中的插件
*
* @param pluginIDs 插件集合
*/
@JSBridge
@JsAccessible
public void updatePluginOnline(JsObject pluginIDs, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
List<PluginMarker> pluginMarkerList = new ArrayList<>();
for (String key : pluginIDs.propertyNames()) {
pluginIDs.property(key).ifPresent(v -> {
pluginMarkerList.add(PluginUtils.createPluginMarker(GeneralUtils.objectToString(v)));
});
}
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
@JSBridge
@JsAccessible
public void updatePluginOnline(String pluginID, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
List<PluginMarker> pluginMarkerList = new ArrayList<>();
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginID));
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
/**
* 搜索在线插件
*
* @param keyword 关键字
*/
@JSBridge
@JsAccessible
public void searchPlugin(String keyword, final JsFunction callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new SearchOnlineExecutor(keyword));
worker.execute();
}
/**
* 从磁盘上选择插件安装包进行安装
*
* @param filePath 插件包的路径
*/
@JSBridge
@JsAccessible
public void installPluginFromDisk(final String filePath, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
File file = new File(filePath);
PluginOperateUtils.installPluginFromDisk(file, jsCallback);
}
/**
* 卸载当前选中的插件
*
* @param pluginInfo 插件信息
*/
@JSBridge
@JsAccessible
public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
}
/**
* 从插件服务器上安装插件
*
* @param pluginInfo 插件的ID
* @param callback 回调函数
*/
@JSBridge
@JsAccessible
public void installPluginOnline(final String pluginInfo, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行插件升级
*
* @param filePath 插件包的路径
*/
@JSBridge
@JsAccessible
public void updatePluginFromDisk(String filePath, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
File file = new File(filePath);
PluginOperateUtils.updatePluginFromDisk(file, jsCallback);
}
/**
* 修改选中的插件的活跃状态
*
* @param pluginID 插件ID
*/
@JSBridge
@JsAccessible
public void setPluginActive(String pluginID, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 选择文件对话框
*
* @return 选择的文件的路径
*/
@JSBridge
@JsAccessible
@Override
public String showFileChooser() {
return super.showFileChooser();
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param filter 文件的后缀
* @return 选择的文件的路径
* 这里换用JFileChooser会卡死,不知道为什么
*/
@JSBridge
@JsAccessible
@Override
public String showFileChooserWithFilter(final String des, final String filter) {
return super.showFileChooserWithFilter(des, filter);
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
@JSBridge
@JsAccessible
public String showFileChooserWithFilters(final String des, final String args) {
RunnableFuture<String> future = new FutureTask<>(() -> {
JFileChooser fileChooser = new JFileChooser();
List<String> filterList = new ArrayList<>();
filterList.add(args);
String[] filters = filterList.toArray(new String[0]);
if (ArrayUtils.isNotEmpty(filters)) {
FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters));
fileChooser.setFileFilter(filter);
}
int result = fileChooser.showOpenDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile().getAbsolutePath();
}
return null;
});
SwingUtilities.invokeLater(future);
try {
return future.get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
@JSBridge
@JsAccessible
public String showFileChooserWithFilters(final String des, final JsObject args) {
RunnableFuture<String> future = new FutureTask<>(() -> {
JFileChooser fileChooser = new JFileChooser();
List<String> filterList = new ArrayList<>();
for (String key : args.propertyNames()) {
args.property(key).ifPresent(v -> {
filterList.add(GeneralUtils.objectToString(v));
});
}
String[] filters = filterList.toArray(new String[0]);
if (ArrayUtils.isNotEmpty(filters)) {
FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters));
fileChooser.setFileFilter(filter);
}
int result = fileChooser.showOpenDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile().getAbsolutePath();
}
return null;
});
SwingUtilities.invokeLater(future);
try {
return future.get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
////////登录相关///////
/**
* 获取系统登录的用户名
*/
@JSBridge
@JsAccessible
public String getLoginInfo(final JsFunction callback) {
registerLoginInfo(callback);
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
/**
* 系统登录注册
*
* @param callback 回调函数
*/
@JSBridge
@JsAccessible
public void registerLoginInfo(final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
String username = DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
if (StringUtils.isEmpty(username)) {
jsCallback.execute(StringUtils.EMPTY);
EventDispatcher.fire(CertificateEvent.LOGOUT, StringUtils.EMPTY);
} else {
jsCallback.execute(username);
EventDispatcher.fire(CertificateEvent.LOGIN, username);
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @param callback 回调函数
*/
@JSBridge
@JsAccessible
public void defaultLogin(String username, String password, final JsFunction callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new PluginLoginExecutor(username, password));
worker.execute();
}
/**
* 清除用户信息
*/
@JsAccessible
@JSBridge
@Override
public void clearUserInfo() {
super.clearUserInfo();
}
/**
* 打开论坛消息界面
*/
@JSBridge
@JsAccessible
@Override
public void getPriviteMessage() {
super.getPriviteMessage();
}
/**
* 忘记密码
*/
@JSBridge
@JsAccessible
@Override
public void forgetHref() {
super.forgetHref();
}
/**
* 立即注册
*/
@JSBridge
@JsAccessible
@Override
public void registerHref() {
super.registerHref();
}
/**
* 使用系统浏览器打开网页
*
* @param url 要打开的网页
*/
@JSBridge
@JsAccessible
@Override
public void openShopUrlAtWebBrowser(String url) {
super.openShopUrlAtWebBrowser(url);
}
}

4
designer-base/src/main/java/com/fr/design/upm/UpmBridge.java

@ -66,6 +66,10 @@ public class UpmBridge {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject(); this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
} }
protected UpmBridge() {
}
/** /**
* 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新 * 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新
* @param callback 安装完成后的回调函数 * @param callback 安装完成后的回调函数

3
designer-base/src/main/java/com/fr/design/upm/UpmFinder.java

@ -15,6 +15,7 @@ import com.fr.event.Listener;
import com.fr.general.GeneralContext; import com.fr.general.GeneralContext;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
import com.fr.stable.os.OperatingSystem;
import com.fr.workspace.Workspace; import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent; import com.fr.workspace.WorkspaceEvent;
@ -31,7 +32,7 @@ public class UpmFinder {
private static final String UPM_DIR = "/upm"; private static final String UPM_DIR = "/upm";
private static final String MAIN_RESOURCE_PATH = UPM_DIR + "/plugin_design.html"; private static final String MAIN_RESOURCE_PATH = UPM_DIR + "/plugin_design.html";
private static final String JXBROWSER = "com.teamdev.jxbrowser.chromium.Browser"; private static final String JXBROWSER = OperatingSystem.isWindows() ? "com.teamdev.jxbrowser.browser.Browser" : "com.teamdev.jxbrowser.chromium.Browser";
public static String installHome = FRContext.getCommonOperator().getWebRootPath(); public static String installHome = FRContext.getCommonOperator().getWebRootPath();

35
designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java

@ -2,14 +2,17 @@ package com.fr.design.upm;
import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.BasicPane;
import com.fr.design.ui.ModernUIPane; import com.fr.design.ui.ModernUIPane;
import com.fr.design.ui.compatible.ModernUIPaneFactory;
import com.fr.design.upm.event.DownloadEvent; import com.fr.design.upm.event.DownloadEvent;
import com.fr.event.Event; import com.fr.event.Event;
import com.fr.event.EventDispatcher; import com.fr.event.EventDispatcher;
import com.fr.event.Listener; import com.fr.event.Listener;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.JSValue; import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import com.teamdev.jxbrowser.js.JsObject;
import java.awt.*; import java.awt.*;
/** /**
@ -29,16 +32,23 @@ public class UpmShowPane extends BasicPane {
UpmShowPane() { UpmShowPane() {
setLayout(new BorderLayout()); setLayout(new BorderLayout());
// 先屏蔽掉这个判断,后续可能修改交互 modernUIPane = ModernUIPaneFactory.modernUIPaneBuilder()
// if (UpmFinder.checkUPMResourcesExist()) { .prepareForV6(new ScriptContextAdapter() {
modernUIPane = new ModernUIPane.Builder<>()
.prepare(new ScriptContextAdapter() {
@Override @Override
public void onScriptContextCreated(ScriptContextEvent event) { public void onScriptContextCreated(ScriptContextEvent event) {
// 6.x
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser())); window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser()));
} }
}) })
.prepareForV7(params -> {
// 7.x
JsObject window = params.frame().executeJavaScript("window");
if (window != null) {
window.putProperty("PluginHelper", NewUpmBridge.getBridge(window));
}
return InjectJsCallback.Response.proceed();
})
.withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()) .withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap())
.build(); .build();
EventDispatcher.listen(DownloadEvent.UPDATE, new Listener<String>() { EventDispatcher.listen(DownloadEvent.UPDATE, new Listener<String>() {
@ -47,23 +57,6 @@ public class UpmShowPane extends BasicPane {
modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()); modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap());
} }
}); });
// } else {
// modernUIPane = new ModernUIPane.Builder<>()
// .withComponent(WarnComponent.KEY)
// .prepare(new ScriptContextAdapter() {
// @Override
// public void onScriptContextCreated(ScriptContextEvent event) {
// JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
// window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser()));
// }
// }).build();
// EventDispatcher.listen(DownloadEvent.SUCCESS, new Listener<String>() {
// @Override
// public void on(Event event, String param) {
// modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap());
// }
// });
// }
add(modernUIPane, BorderLayout.CENTER); add(modernUIPane, BorderLayout.CENTER);
} }
} }

30
designer-base/src/main/java/com/fr/design/upm/exec/NewUpmBrowserExecutor.java

@ -0,0 +1,30 @@
package com.fr.design.upm.exec;
import com.fr.design.bridge.exec.JSExecutor;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-18
*/
public class NewUpmBrowserExecutor implements JSExecutor {
public static NewUpmBrowserExecutor create(JsObject window, JsFunction callback) {
return new NewUpmBrowserExecutor(window, callback);
}
private final JsFunction callback;
private final JsObject window;
private NewUpmBrowserExecutor(JsObject window, JsFunction callback) {
this.window = window;
this.callback = callback;
}
@Override
public void executor(String newValue) {
callback.invoke(window, newValue);
}
}

7
designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java

@ -19,6 +19,7 @@ import com.fr.design.designer.creator.XEditorHolder;
import com.fr.design.designer.creator.XElementCase; import com.fr.design.designer.creator.XElementCase;
import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.creator.cardlayout.XCardAddButton;
import com.fr.design.designer.creator.cardlayout.XCardSwitchButton; import com.fr.design.designer.creator.cardlayout.XCardSwitchButton;
import com.fr.design.designer.creator.cardlayout.XWCardLayout; import com.fr.design.designer.creator.cardlayout.XWCardLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
@ -623,7 +624,9 @@ public class EditingMouseListener extends MouseInputAdapter {
creator = processTopLayoutMouseClick(creator); creator = processTopLayoutMouseClick(creator);
if (creator != null) { if (creator != null) {
if (e.getClickCount() == 1 && designer.getCursor().getType() != Cursor.HAND_CURSOR) { // 点击不在tab块的button中
boolean clickedNonCardButton = !creator.acceptType(XCardAddButton.class, XCardSwitchButton.class);
if (clickedNonCardButton && e.getClickCount() == 1 && designer.getCursor().getType() != Cursor.HAND_CURSOR) {
setCoverPaneNotDisplay(creator, e, false); setCoverPaneNotDisplay(creator, e, false);
selectionModel.selectACreatorAtMouseEvent(e); selectionModel.selectACreatorAtMouseEvent(e);
refreshTopXCreator(); refreshTopXCreator();
@ -631,7 +634,7 @@ public class EditingMouseListener extends MouseInputAdapter {
for (XCreator xCreator : xCreators) { for (XCreator xCreator : xCreators) {
xCreator.setSelected(true); xCreator.setSelected(true);
} }
} else if (responseTabLayout(oldCreator, e)) { } else if (clickedNonCardButton && responseTabLayout(oldCreator, e)) {
// do nothing // do nothing
} else { } else {
creator.respondClick(this, e); creator.respondClick(this, e);

Loading…
Cancel
Save