Browse Source

Pull request #14751: REPORT-133275 & REPORT-133276

Merge in DESIGN/design from ~VITO/c-design:fbp/release to fbp/release

* commit '9a27e4f38dc47c6726cf4b612a515ce1d637aa57':
  无jira任务 代码质量
  REPORT-133276  fbp设计器完全删除jxbrowser 6.x
  无jira任务 子类方法添加注解
  REPORT-133275 fbp设计器清理存在javafx webview替代页面
fbp/merge
vito-刘恒霖 4 months ago
parent
commit
a65e663b68
  1. 5
      build.gradle
  2. 16
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  3. 25
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  4. 42
      designer-base/src/main/java/com/fr/design/extra/LoginDialog.java
  5. 200
      designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java
  6. 54
      designer-base/src/main/java/com/fr/design/extra/LoginWebPane.java
  7. 2
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  8. 601
      designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java
  9. 112
      designer-base/src/main/java/com/fr/design/extra/PluginWebPane.java
  10. 32
      designer-base/src/main/java/com/fr/design/extra/QQLoginDialog.java
  11. 46
      designer-base/src/main/java/com/fr/design/extra/ShopDialog.java
  12. 31
      designer-base/src/main/java/com/fr/design/extra/ShopManagerPane.java
  13. 36
      designer-base/src/main/java/com/fr/design/extra/ShopPaneConfig.java
  14. 307
      designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java
  15. 4
      designer-base/src/main/java/com/fr/design/extra/exe/PluginLoginExecutor.java
  16. 47
      designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java
  17. 6
      designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java
  18. 30
      designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginBrowserExecutor.java
  19. 3
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java
  20. 18
      designer-base/src/main/java/com/fr/design/login/message/NotificationActionType.java
  21. 32
      designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java
  22. 55
      designer-base/src/main/java/com/fr/design/os/impl/SupportOSImpl.java
  23. 91
      designer-base/src/main/java/com/fr/design/ui/Assistant.java
  24. 135
      designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java
  25. 364
      designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java
  26. 55
      designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java
  27. 45
      designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java
  28. 515
      designer-base/src/main/java/com/fr/design/upm/UpmBridge.java
  29. 122
      designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java
  30. 30
      designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java
  31. 4
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/ComposedNativeBridges.java
  32. 3
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeAuthBridge.java
  33. 2
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeBrowserBridge.java
  34. 21
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java
  35. 5
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeTaskBridge.java
  36. 22
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/SafeJSFunctionInvoker.java
  37. 5
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/cell/model/PluginModel.java
  38. 46
      designer-realize/src/main/java/com/fr/design/mainframe/bbs/BBSDialog.java
  39. 73
      designer-realize/src/main/java/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java
  40. 11
      designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java

5
build.gradle

@ -95,7 +95,6 @@ allprojects {
// messenger
implementation 'com.fr.messenger:fine-messenger:' + carinaVersion
implementation 'com.install4j:install4j-runtime:8.0.4'
implementation 'com.fr.third:jxbrowser:6.23'
implementation "com.fr.third:jxbrowser-v7:${jxBrowserVersion}"
implementation "com.fr.third:jxbrowser-swing-v7:${jxBrowserVersion}"
implementation 'com.fr.third.server:servlet-api:3.0'
@ -131,18 +130,14 @@ allprojects {
// mac_x64, mac_aarch64, windows_x64
if (OperatingSystem.current().isMacOsX() && "aarch64".equals(System.getProperty("os.arch"))) {
dependencies {
// jxbrowser 6.23M16.23jar还是需要留着
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation "com.fr.third:jxbrowser-mac-arm-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isMacOsX()) {
dependencies {
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation "com.fr.third:jxbrowser-mac-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isWindows()) {
dependencies {
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation "com.fr.third:jxbrowser-win64-v7:${jxBrowserVersion}"
}
}

16
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -1020,22 +1020,6 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
designerLoginConfigManager.setPluginRemindOnFirstLaunch(pluginRemindOnFirstLaunch);
}
public boolean isUseOldVersionLogin() {
return designerLoginConfigManager.isUseOldVersionLogin();
}
public void setUseOldVersionLogin(boolean useOldVersionLogin) {
designerLoginConfigManager.setUseOldVersionLogin(useOldVersionLogin);
}
public boolean isUseNewPluginFirst() {
return designerLoginConfigManager.isUseNewPluginFirst();
}
public void setUseNewPluginFirst(boolean useNewPluginFirst) {
designerLoginConfigManager.setUseNewPluginFirst(useNewPluginFirst);
}
/**
* 内置服务器是否使用时启动
*

25
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -310,10 +310,6 @@ public class PreferencePane extends BasicPane {
cell(createLengthPane()),
// 服务器设置
cell(createServerPane()),
// 插件管理设置
cell(createUpmSelectorPane()).with(it -> it.setVisible(!OperatingSystem.isLinux() && JdkVersion.LE_8.support())),
// 登录选项
cell(createLoginSelectorPane()).with(it -> it.setVisible(SupportOSImpl.DESIGNER_LOGIN.support())),
// Oracle设置
cell(createOraclePane()),
// 内存设置
@ -968,11 +964,7 @@ public class PreferencePane extends BasicPane {
this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort()));
if (useOptimizedUPMCheckbox != null) {
useOptimizedUPMCheckbox.setSelected(checkOptimizedUPMUse());
}
if (useNewVersionLoginCheckbox != null) {
useNewVersionLoginCheckbox.setSelected(!DesignerEnvManager.getEnvManager().isUseOldVersionLogin());
useOptimizedUPMCheckbox.setSelected(true);
}
useUniverseDBMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseUniverseDBM());
@ -1011,15 +1003,6 @@ public class PreferencePane extends BasicPane {
this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled());
}
private boolean checkOptimizedUPMUse() {
//如果是没手动配置过则默认开启
//isUseNewPluginFirst如果为true说明没手动配置过,直接开启
//走到这里说明checkBox不为空,机型肯定符合
return DesignerEnvManager.getEnvManager().isUseNewPluginFirst()
|| ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter();
}
private int chooseCase(int sign) {
switch (sign) {
case 0:
@ -1086,8 +1069,6 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setImageCompress(this.imageCompressPanelCheckBox.isSelected());
boolean optimizedUPMFlag = this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected();
designerEnvManager.setUseOptimizedUPM4Adapter(optimizedUPMFlag);
//只有取消掉使用新插件管理器这个选项才需要把useNewPluginFirst置false(意味着用户手动配置了,如果勾选着的话,这个useNewPluginFirst为true就行了)
designerEnvManager.setUseNewPluginFirst(optimizedUPMFlag);
boolean cloudDelayFlag = this.cloudAnalyticsDelayCheckBox.isSelected();
designerEnvManager.setCloudAnalyticsDelay(cloudDelayFlag);
// cloudDelayFlag默认为true,如果用户手动配置过才会是false,则后续的云端运维配置都按照用户意愿来
@ -1125,10 +1106,6 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setAutoPushUpdateEnabled(this.autoPushUpdateCheckBox.isSelected());
}
if (useNewVersionLoginCheckbox != null) {
designerEnvManager.setUseOldVersionLogin(!this.useNewVersionLoginCheckbox.isSelected());
}
designerEnvManager.setUndoLimit(maxUndoLimit.getSelectedIndex() * SELECTED_INDEX_5);
if (maxUndoLimit.getSelectedIndex() == SELECTED_INDEX_5) {
designerEnvManager.setUndoLimit(MAX_UNDO_LIMIT_50);

42
designer-base/src/main/java/com/fr/design/extra/LoginDialog.java

@ -1,42 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StableUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by vito on 2017/5/5.
*/
public class LoginDialog extends UIDialog {
private static final Dimension DEFAULT_SHOP = new Dimension(401, 301);
public LoginDialog(Frame frame, Component pane) {
super(frame);
init(pane);
}
public LoginDialog(Dialog dialog, Component pane) {
super(dialog);
init(pane);
}
private void init(Component pane) {
if (StableUtils.getMajorJavaVersion() >= 8) {
setUndecorated(true);
}
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT_SHOP);
GUICoreUtils.centerWindow(this);
setResizable(false);
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

200
designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java

@ -1,200 +0,0 @@
package com.fr.design.extra;
import com.fanruan.carina.Carina;
import com.fanruan.cloud.FanruanCloud;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.login.service.DesignerLoginClient;
import com.fr.design.login.service.DesignerLoginResult;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpClient;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javafx.concurrent.Task;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author vito
*/
public class LoginWebBridge {
//最低消息的条数
private static final int MIN_MESSAGE_COUNT = 0;
//网络连接失败
private static final String NET_FAILED = "-4";
//用户名,密码为空
private static final String LOGIN_INFO_EMPTY = "-5";
private static final Color LOGIN_BACKGROUND = new Color(184, 220, 242);
private static LoginWebBridge helper;
//消息条数
private int messageCount;
private UIDialog uiDialog;
private UIDialog qqDialog;
private UILabel uiLabel;
private WebEngine webEngine;
private LoginWebBridge() {
}
public static LoginWebBridge getHelper() {
if (helper != null) {
return helper;
}
synchronized (LoginWebBridge.class) {
if (helper == null) {
helper = new LoginWebBridge();
}
return helper;
}
}
public static LoginWebBridge getHelper(WebEngine webEngine) {
getHelper();
helper.setWebEngine(webEngine);
return helper;
}
public void setWebEngine(WebEngine webEngine) {
this.webEngine = webEngine;
}
public int getMessageCount() {
return messageCount;
}
/**
* 设置获取的消息长度并设置显示
*
* @param count
*/
public void setMessageCount(int count) {
if (count == MIN_MESSAGE_COUNT) {
Carina.config(FineBBSConfigProvider.class).setBbsUsername(DesignerEnvManager.getEnvManager().getDesignerLoginUsername());
return;
}
this.messageCount = count;
StringBuilder sb = new StringBuilder();
sb.append(StringUtils.BLANK).append(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())
.append("(").append(this.messageCount)
.append(")").append(StringUtils.BLANK);
Carina.config(FineBBSConfigProvider.class).setBbsUsername(sb.toString());
}
public void setQQDialog(UIDialog qqDialog) {
closeQQWindow();
this.qqDialog = qqDialog;
}
public void setDialogHandle(UIDialog uiDialog) {
closeWindow();
this.uiDialog = uiDialog;
}
public void setUILabel(UILabel uiLabel) {
this.uiLabel = uiLabel;
}
/**
* 测试论坛网络连接
*
* @return
*/
private boolean testConnection() {
HttpClient client = new HttpClient(CloudCenter.getInstance().acquireUrlByKind("bbs.test"));
return client.isServerAlive();
}
/**
* 注册页面
*/
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 忘记密码
*/
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @return 登录信息标志
*/
public void defaultLogin(String username, String password, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new PluginLoginExecutor(username, password));
ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("bbsDefaultLogin"));
es.submit(task);
es.shutdown();
}
/**
* 登录操作
*
* @param userInfo 登录信息
* @param password 密码
* @return 登录信息标志
*/
public String login(String userInfo, String password) {
DesignerLoginClient client = new DesignerLoginClient();
DesignerLoginResult result = client.login(userInfo, password);
int uid = result.getUid();
if (uid > 0) {
closeWindow();
}
return String.valueOf(uid);
}
/**
* 关闭窗口
*/
public void closeWindow() {
if (uiDialog != null) {
uiDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
uiDialog.setVisible(false);
}
}
/**
* 关闭QQ授权窗口
*/
public void closeQQWindow() {
if (qqDialog != null) {
qqDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
qqDialog.setVisible(false);
}
}
public void openUrlAtLocalWebBrowser(WebEngine eng, String url) {
// do nothing
}
}

54
designer-base/src/main/java/com/fr/design/extra/LoginWebPane.java

@ -1,54 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.FineJOptionPane;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.*;
/**
* Created by zhaohehe on 16/7/26.
*/
public class LoginWebPane extends JFXPanel {
public LoginWebPane(final String installHome) {
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
LoginWebPane.this.setScene(scene);
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.load("file:///" + installHome + "/scripts/login.html");
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
showAlert(event.getData());
}
});
JSObject obj = (JSObject) webEngine.executeScript("window");
obj.setMember("LoginHelper", LoginWebBridge.getHelper(webEngine));
webView.setContextMenuEnabled(false);//屏蔽右键
root.setCenter(webView);
}
});
}
private void showAlert(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(LoginWebPane.this, message);
}
});
}
}

2
designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java

@ -30,13 +30,11 @@ import com.fr.plugin.view.PluginView;
import com.fr.plugin.xml.PluginElementName;
import com.fr.plugin.xml.PluginXmlElement;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.JSArray;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.File;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;

601
designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java

@ -1,601 +0,0 @@
package com.fr.design.extra;
import com.fanruan.carina.Carina;
import com.fanruan.cloud.FanruanCloud;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.UIDialog;
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.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.DesignerLoginSource;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.utils.concurrent.ThreadFactoryBuilder;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
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 javafx.concurrent.Task;
import javafx.scene.web.WebEngine;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 开放给Web组件的接口,用于安装,卸载,更新以及更改插件可用状态
*/
public class PluginWebBridge {
private static final String THREAD_NAME_TEMPLATE = "pluginbridge-thread-%s";
private static final String ACTION = "action";
private static final String KEYWORD = "keyword";
private static final String PLUGIN_INFO = "pluginInfo";
private static final int COREPOOLSIZE = 3;
private static final int MAXPOOLSIZE = 5;
private static PluginWebBridge helper;
private UIDialog uiDialog;
private ACTIONS actions;
private Map<String, Object> config;
private WebEngine webEngine;
private ExecutorService threadPoolExecutor = new ThreadPoolExecutor(COREPOOLSIZE, MAXPOOLSIZE,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(COREPOOLSIZE),
new ThreadFactoryBuilder().setNameFormat(THREAD_NAME_TEMPLATE).build());
private PluginWebBridge() {
}
public static PluginWebBridge getHelper() {
if (helper != null) {
return helper;
}
synchronized (PluginWebBridge.class) {
if (helper == null) {
helper = new PluginWebBridge();
}
return helper;
}
}
public static PluginWebBridge getHelper(WebEngine webEngine) {
getHelper();
helper.setEngine(webEngine);
return helper;
}
/**
* 获取打开动作配置
*
* @return 配置信息
*/
public String getRunConfig() {
if (actions != null) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(ACTION, actions.getContext());
Set<String> keySet = config.keySet();
for (String key : keySet) {
jsonObject.put(key, config.get(key).toString());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return jsonObject.toString();
}
return StringUtils.EMPTY;
}
/**
* 配置打开动作
*
* @param action 动作
* @param config 参数
*/
public void setRunConfig(ACTIONS action, Map<String, Object> config) {
this.actions = action;
this.config = config;
}
/**
* 清楚打开动作
*/
public void clearRunConfig() {
this.actions = null;
this.config = null;
}
/**
* 打开时搜索
*
* @param keyword 关键词
*/
public void openWithSearch(String keyword) {
HashMap<String, Object> map = new HashMap<String, Object>(2);
map.put(KEYWORD, keyword);
setRunConfig(ACTIONS.SEARCH, map);
}
/**
* 根据插件信息跳转到应用中心
*
* @param keyword
* @param pluginInfo
*/
public void showResultInStore(String keyword, String pluginInfo) {
HashMap<String, Object> map = new HashMap<>();
map.put(KEYWORD, keyword);
map.put(PLUGIN_INFO, pluginInfo);
setRunConfig(ACTIONS.SHOW_RESULT, map);
}
public void setEngine(WebEngine webEngine) {
this.webEngine = webEngine;
}
public void setDialogHandle(UIDialog uiDialog) {
closeWindow();
this.uiDialog = uiDialog;
}
/**
* 从插件服务器上安装插件
*
* @param pluginInfo 插件的ID
* @param callback 回调函数
*/
public void installPluginOnline(final String pluginInfo, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行安装
*
* @param filePath 插件包的路径
*/
public void installPluginFromDisk(final String filePath, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
File file = new File(filePath);
PluginOperateUtils.installPluginFromDisk(file, jsCallback);
}
/**
* 卸载当前选中的插件
*
* @param pluginInfo 插件信息
*/
public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
}
/**
* 从插件服务器上更新选中的插件
*
* @param pluginIDs 插件集合
*/
public void updatePluginOnline(JSObject pluginIDs, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
String[] pluginInfos = jsObjectToStringArray(pluginIDs);
List<PluginMarker> pluginMarkerList = new ArrayList<PluginMarker>();
for (int i = 0; i < pluginInfos.length; i++) {
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginInfos[i]));
}
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行插件升级
*
* @param filePath 插件包的路径
*/
public void updatePluginFromDisk(String filePath, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
File file = new File(filePath);
PluginOperateUtils.updatePluginFromDisk(file, jsCallback);
}
/**
* 修改选中的插件的活跃状态
*
* @param pluginID 插件ID
*/
public void setPluginActive(String pluginID, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 已安装插件检查更新
*/
public void readUpdateOnline(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new ReadUpdateOnlineExecutor());
threadPoolExecutor.submit(task);
}
/**
* 选择文件对话框
*
* @return 选择的文件的路径
*/
public String showFileChooser() {
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param filter 文件的后缀
* @return 选择的文件的路径
* 这里换用JFileChooser会卡死,不知道为什么
*/
public String showFileChooserWithFilter(String des, String filter) {
FileChooser fileChooser = new FileChooser();
if (StringUtils.isNotEmpty(filter)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filter));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
public String showFileChooserWithFilters(String des, JSObject args) {
FileChooser fileChooser = new FileChooser();
String[] filters = jsObjectToStringArray(args);
if (ArrayUtils.isNotEmpty(filters)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filters));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 获取已经安装的插件的数组
*
* @return 已安装的插件组成的数组
*/
public void getInstalledPlugins(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetInstalledPluginsExecutor());
threadPoolExecutor.submit(task);
}
private String[] jsObjectToStringArray(JSObject obj) {
if (obj == null) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
int len = (int) obj.getMember("length");
List<String> list = new ArrayList<>();
for (int i = 0; i < len; i++) {
list.add(obj.getSlot(i).toString());
}
return list.toArray(new String[len]);
}
/**
* 搜索在线插件
*
* @param keyword 关键字
*/
public void searchPlugin(String keyword, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new SearchOnlineExecutor(keyword));
threadPoolExecutor.submit(task);
}
/**
* 根据条件获取在线插件的
*
* @param category 分类
* @param seller 卖家性质
* @param fee 收费类型
* @param callback 回调函数
*/
public void getPluginFromStore(String category, String seller, String fee, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginFromStoreExecutor(category, seller, fee, ""));
threadPoolExecutor.submit(task);
}
/**
* 根据条件获取在线插件
*
* @param info 插件信息
* @param callback 回调函数
*/
public void getPluginFromStoreNew(String info, final JSObject callback) {
try {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginFromStoreExecutor(new JSONObject(info)));
threadPoolExecutor.submit(task);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
public void getPluginPrefix(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginPrefixExecutor());
threadPoolExecutor.submit(task);
}
/**
* 在线获取插件分类
*
* @param callback 回调函数
*/
public void getPluginCategories(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginCategoriesExecutor());
threadPoolExecutor.submit(task);
}
/**
* 展示一个重启的对话框(少用,莫名其妙会有bug)
*
* @param message 展示的消息
*/
public void showRestartMessage(String message) {
int rv = JOptionPane.showOptionDialog(
null,
message,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer_Later")},
null
);
if (rv == JOptionPane.OK_OPTION) {
RestartHelper.restart();
}
}
/**
* 关闭窗口
*/
public void closeWindow() {
if (uiDialog != null) {
uiDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
uiDialog.setVisible(false);
}
if (uiDialog == DesignerPluginContext.getPluginDialog()) {
DesignerPluginContext.setPluginDialog(null);
}
}
/**
* 窗口是否无装饰(判断是否使用系统标题栏)
*/
public boolean isCustomTitleBar() {
if (uiDialog != null) {
return uiDialog.isUndecorated();
}
return false;
}
/**
* 获取系统登录的用户名
*
* @param callback
*/
public String getLoginInfo(final JSObject callback) {
registerLoginInfo(callback);
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
/**
* 系统登录注册
*
* @param callback
*/
public void registerLoginInfo(final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.getLoginInfo(jsCallback);
}
/**
* 打开论坛消息界面
*/
public void getPriviteMessage() {
try {
LocaleMark<String> spaceMark = LocaleCenter.getMark(BbsSpaceMark.class);
Desktop.getDesktop().browse(new URI(spaceMark.getValue()));
} catch (Exception exp) {
FineLoggerFactory.getLogger().info(exp.getMessage());
}
}
/**
* 打开登录页面
*/
public void loginContent() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
UserLoginContext.fireLoginContextListener(DesignerLoginSource.NORMAL);
}
});
}
/**
* 在本地浏览器里打开url
* tips:重载的时候,需要给js调用的方法需要放在前面,否则可能不会被调用(此乃坑)
* 所以最好的是不要重载在js可以访问的接口文件中
*
* @param url 要打开的地址
*/
public void openShopUrlAtWebBrowser(String url) {
openUrlAtLocalWebBrowser(webEngine, url);
}
/**
* 在本地浏览器里打开url
*
* @param eng web引擎
* @param url 要打开的地址
*/
public void openUrlAtLocalWebBrowser(WebEngine eng, String url) {
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (NullPointerException e) {
//此为uri为空时抛出异常
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} catch (IOException e) {
//此为无法获取系统默认浏览器
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* 注册页面
*/
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/*-------------------------------登录部分的处理----------------------------------*/
/**
* 忘记密码
*/
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @return 登录信息标志
*/
public void defaultLogin(String username, String password, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new PluginLoginExecutor(username, password));
threadPoolExecutor.submit(task);
}
/**
* 通过QQ登录后通知登录
*/
public void ucsynLogin(long uid, String username, String password, final JSONObject callback) {
}
/**
* 清除用户信息
*/
public void clearUserInfo() {
Carina.config(FineBBSConfigProvider.class).setBbsUsername(StringUtils.EMPTY);
}
public void getPackInfo(final JSObject callback){
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
jsCallback.execute(StringUtils.EMPTY);
}
/**
* 初始化设计器部分
*/
public void initExtraDiff(final JSObject callback) {
//todo 初始化设计器其他部分
}
/**
* 国际化(用来做兼容暂时不删)
*/
public String parseI18(final String key) {
return com.fr.design.i18n.Toolkit.i18nText(key);
}
/**
* 是否是在设计器中操作
*/
public boolean isDesigner() {
return true;
}
/**
* 动作枚举
*/
public enum ACTIONS {
SEARCH("search"), SHOW_RESULT("showResult");
private String context;
ACTIONS(String context) {
this.context = context;
}
public String getContext() {
return context;
}
}
}

112
designer-base/src/main/java/com/fr/design/extra/PluginWebPane.java

@ -1,112 +0,0 @@
package com.fr.design.extra;
import com.fr.base.TemplateUtils;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.general.GeneralContext;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* Created by richie on 16/3/19.
*/
public class PluginWebPane extends JFXPanel {
private static final String RESOURCE_URL = "resourceURL";
private static final String LANGUAGE = "language";
private static final String URL_PLUS = "+";
private static final String URL_SPACING = "%20";
private static final String URL_PREFIX = "file:///";
private WebEngine webEngine;
public PluginWebPane(final String installHome, final String mainJs) {
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
PluginWebPane.this.setScene(scene);
WebView webView = new WebView();
webEngine = webView.getEngine();
try{
String htmlString = getRenderedHtml(installHome, mainJs);
webEngine.loadContent(htmlString);
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
showAlert(event.getData());
}
});
JSObject obj = (JSObject) webEngine.executeScript("window");
obj.setMember("PluginHelper", PluginWebBridge.getHelper(webEngine));
webView.setContextMenuEnabled(false);//屏蔽右键
root.setCenter(webView);
}catch (Exception e){
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
});
}
private String getRenderedHtml(String installHome, String mainJs) throws IOException {
InputStream inp = IOUtils.readResource(StableUtils.pathJoin(installHome, mainJs));
if (inp == null) {
throw new IOException("Not found template: " + mainJs);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inp, StableUtils.RESOURCE_ENCODER));
BufferedReader read = new BufferedReader(reader);
StringBuffer sb = new StringBuffer();
String line;
Map<String, Object> map4Tpl = new HashMap<String, Object>();
//URL中关于空格的编码与空格所在位置相关:空格被编码成+的情况只能在查询字符串部分出现,而被编码成%20则可以出现在路径和查询字符串中
//URLEncoder会将空格转成+,这边需要+转成%20
map4Tpl.put(RESOURCE_URL, URL_PREFIX + URLEncoder.encode(installHome, EncodeConstants.ENCODING_UTF_8).replace(URL_PLUS, URL_SPACING));
map4Tpl.put(LANGUAGE, GeneralContext.getLocale().toString());
while ((line = read.readLine()) != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append(line);
}
String htmlString = StringUtils.EMPTY;
try{
htmlString = TemplateUtils.renderParameter4Tpl(sb.toString(), map4Tpl);
}catch (Exception e){
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
reader.close();
inp.close();
return htmlString;
}
private void showAlert(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(PluginWebPane.this, message);
}
});
}
}

32
designer-base/src/main/java/com/fr/design/extra/QQLoginDialog.java

@ -1,32 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by zhaohehe on 16/7/28.
*/
public class QQLoginDialog extends UIDialog {
private static final Dimension DEFAULT_SHOP = new Dimension(700, 500);
public QQLoginDialog(Frame frame, Component pane) {
super(frame);
setUndecorated(true);
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT_SHOP);
GUICoreUtils.centerWindow(this);
setResizable(false);
setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager"));
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

46
designer-base/src/main/java/com/fr/design/extra/ShopDialog.java

@ -1,46 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.jdk.JdkVersion;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StableUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by vito on 16/4/18.
*/
public class ShopDialog extends UIDialog {
public ShopDialog(Frame frame, BasicPane pane) {
super(frame);
if (StableUtils.getMajorJavaVersion() >= 8) {
setUndecorated(true);
}
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(createDefaultDimension());
GUICoreUtils.centerWindow(this);
setResizable(false);
DesignerPluginContext.setPluginDialog(this);
}
private Dimension createDefaultDimension() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// jdk11 分辨率较低 缩放较大时 屏幕高度小于或接近设定的高度 需要调整下
if (JdkVersion.GE_9.support() && screenSize.height - 700 < 50) {
return new Dimension(900, screenSize.height - 100);
} else {
return new Dimension(900, 700);
}
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

31
designer-base/src/main/java/com/fr/design/extra/ShopManagerPane.java

@ -1,31 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* @author richie
* @date 2015-03-09
* @since 8.0
* 应用中心的构建采用JavaScript代码来动态实现,但是不总是依赖于服务器端的HTML
* 采用JDK提供的JavaScript引擎,实际是用JavaScript语法实现Java端的功能,并通过JavaScript引擎动态调用
* JavaScript放在安装目录下的scripts/store目录下,检测到新版本的时候,可以通过更新这个目录下的文件实现热更新
* 不直接嵌入WebView组件的原因是什么呢?
* 因为如果直接嵌入WebView,和设计器的交互就需要预先设定好,这样灵活性会差很多,而如果使用JavaScript引擎,
* 就可以直接在JavaScript中和WebView组件做交互,而同时JavaScript中可以调用任何的设计器API.
*/
public class ShopManagerPane extends BasicPane {
public ShopManagerPane(Component webPane) {
setLayout(new BorderLayout());
add(webPane, BorderLayout.CENTER);
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager");
}
}

36
designer-base/src/main/java/com/fr/design/extra/ShopPaneConfig.java

@ -1,36 +0,0 @@
package com.fr.design.extra;
import javafx.embed.swing.JFXPanel;
/**
* Created by vito on 2016/9/28.
*/
public abstract class ShopPaneConfig {
private String mainJS;
private String scriptsId;
private JFXPanel webPane;
public ShopPaneConfig() {
this.mainJS = setMainJS();
this.scriptsId = setScriptsId();
this.webPane = setWebPane();
}
abstract String setMainJS();
abstract String setScriptsId();
abstract JFXPanel setWebPane();
public String getMainJS() {
return mainJS;
}
public String getScriptsId() {
return scriptsId;
}
public JFXPanel getWebPane() {
return webPane;
}
}

307
designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java

@ -1,307 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.CloudCenter;
import com.fr.general.CommonIOUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralContext;
import com.fr.general.IOUtils;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.PluginStoreConfig;
import com.fr.plugin.PluginStoreConstants;
import com.fr.stable.CommonUtils;
import com.fr.stable.EnvChangedListener;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StableUtils;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.concurrent.ExecutionException;
/**
* 在合适的 jre 环境下创建带有 WebView 的窗口
*
* @author vito
* @date 2016/9/28
*/
public class WebViewDlgHelper {
private static final String LATEST = "latest";
private static final String SHOP_SCRIPTS = "shop_scripts";
private static final int VERSION_8 = 8;
private static String installHome = PluginStoreConstants.getLocalInstallHome();
private static final String MAIN_JS_PATH = "/scripts/plugin.html";
static {
GeneralContext.addEnvChangedListener(new EnvChangedListener() {
@Override
public void envChanged() {
installHome = PluginStoreConstants.getLocalInstallHome();
}
});
}
public static void createPluginDialog() {
if (StableUtils.getMajorJavaVersion() >= VERSION_8) {
String mainJsPath = StableUtils.pathJoin(installHome, MAIN_JS_PATH);
File file = new File(mainJsPath);
if (!file.exists()) {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Install"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(SHOP_SCRIPTS);
}
return;
}
// 检测更新前先刷新一下版本号
PluginStoreConstants.refreshProps();
String jarVersion = PluginStoreConfig.getInstance().getEnvVersion();
if (ComparatorUtils.equals(jarVersion, ProductConstants.VERSION)) {
updateShopScripts(SHOP_SCRIPTS);
showPluginDlg();
} else {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Install_Version"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(SHOP_SCRIPTS);
deleteExtraFile(StableUtils.pathJoin(installHome, "plugin.html"));
}
}
} else {
BasicPane traditionalStorePane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager");
}
};
traditionalStorePane.setLayout(new BorderLayout());
traditionalStorePane.add(initTraditionalStore(), BorderLayout.CENTER);
UIDialog dlg = new ShopDialog(DesignerContext.getDesignerFrame(), traditionalStorePane);
dlg.setVisible(true);
}
}
/**
* 检查script文件夹中的plugin.html文件
*/
public static void checkAndCopyMainFile(String indexPath, String mainJsPath) {
File file = new File(indexPath);
if (!file.exists()) {
copyMainFile(mainJsPath);
}
}
/**
* 將script文件夹中的plugin.html文件复制到webreport下
*/
private static void copyMainFile(String mainJsPath) {
try {
CommonIOUtils.copy(new File(mainJsPath), new File(installHome));
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除9.0工程下无用的plugin.html文件
*
* @param filePath 待删除文件路径
*/
private static void deleteExtraFile(String filePath) {
CommonIOUtils.deleteFile(new File(filePath));
}
/**
* 以关键词打开设计器商店
*
* @param keyword 关键词
*/
public static void createPluginDialog(String keyword) {
PluginWebBridge.getHelper().openWithSearch(keyword);
createPluginDialog();
}
/**
* 以关键词打开设计器商店显示搜索结果
*
* @param keyword
* @param data
*/
@Deprecated
public static void showPluginInStore(String keyword, String data) {
PluginWebBridge.getHelper().showResultInStore(keyword, data);
createPluginDialog();
}
public static void createLoginDialog() {
if (StableUtils.getMajorJavaVersion() >= VERSION_8) {
File file = new File(StableUtils.pathJoin(installHome, "scripts"));
if (!file.exists()) {
confirmDownLoadShopJS();
} else {
showLoginDlg(DesignerContext.getDesignerFrame());
updateShopScripts(SHOP_SCRIPTS);
}
}
}
public static void createLoginDialog(Window parent) {
if (StableUtils.getMajorJavaVersion() >= VERSION_8) {
File file = new File(StableUtils.pathJoin(installHome, "scripts"));
if (!file.exists()) {
confirmDownLoadShopJS();
} else {
showLoginDlg(parent);
updateShopScripts(SHOP_SCRIPTS);
}
}
}
private static void confirmDownLoadShopJS() {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Install"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(SHOP_SCRIPTS);
}
}
private static void showPluginDlg() {
try {
Class<?> clazz = Class.forName("com.fr.design.extra.PluginWebPane");
Constructor constructor = clazz.getConstructor(String.class, String.class);
Component webPane = (Component) constructor.newInstance(installHome, MAIN_JS_PATH);
BasicPane managerPane = new ShopManagerPane(webPane);
UIDialog dlg = new ShopDialog(DesignerContext.getDesignerFrame(), managerPane);
PluginWebBridge.getHelper().setDialogHandle(dlg);
dlg.setVisible(true);
DesignerLoginUtils.showPluginRemindOnFirstLaunch(dlg);
} catch (Exception e) {
// ignored
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private static void showLoginDlg(Window window) {
try {
Class<?> clazz = Class.forName("com.fr.design.extra.LoginWebPane");
Constructor constructor = clazz.getConstructor(String.class);
Component webPane = (Component) constructor.newInstance(installHome);
UIDialog qqdlg;
if (window instanceof Dialog) {
qqdlg = new LoginDialog((Dialog) window, webPane);
} else {
qqdlg = new LoginDialog((Frame) window, webPane);
}
LoginWebBridge.getHelper().setDialogHandle(qqdlg);
qqdlg.setVisible(true);
} catch (Throwable ignored) {
// ignored
}
}
private static Component initTraditionalStore() {
UITabbedPane tabbedPane = new UITabbedPane();
PluginInstalledPane installedPane = new PluginInstalledPane();
tabbedPane.addTab(installedPane.tabTitle(), installedPane);
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Update"), new PluginUpdatePane(tabbedPane));
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_All_Plugins"), new PluginFromStorePane(tabbedPane));
return tabbedPane;
}
private static void downloadShopScripts(final String scriptsId) {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return PluginUtils.downloadShopScripts(scriptsId, new Process<Double>() {
@Override
public void process(Double integer) {
// 这个注释毫无意义,就是为了通过SonarQube
}
});
}
@Override
protected void done() {
try {
if (get()) {
File scriptZip = new File(StableUtils.pathJoin(PluginConstants.DOWNLOAD_PATH, PluginConstants.TEMP_FILE));
if (scriptZip.exists()) {
IOUtils.unzip(scriptZip, installHome);
CommonUtils.deleteFile(scriptZip);
}
PluginStoreConstants.refreshProps(); // 下载完刷新一下版本号等
FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Installed"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), JOptionPane.INFORMATION_MESSAGE);
}
} catch (InterruptedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}.execute();
}
private static void updateShopScripts(final String scriptsId) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
String url = CloudCenter.getInstance().acquireUrlByKind("shop.plugin.update");
if (url != null) {
String text = HttpToolbox.get(url + "?" + PluginUtils.FR_VERSION + "=" + ProductConstants.VERSION + "&version=" + PluginStoreConfig.getInstance().getVersion());
JSONObject resultJSONObject = new JSONObject(text);
String isLatest = resultJSONObject.optString("result");
if (!ComparatorUtils.equals(isLatest, LATEST)) {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Update"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(scriptsId);
}
}
}
return null;
}
}.execute();
}
}

4
designer-base/src/main/java/com/fr/design/extra/exe/PluginLoginExecutor.java

@ -1,6 +1,5 @@
package com.fr.design.extra.exe;
import com.fr.design.extra.LoginWebBridge;
import com.fr.design.extra.Process;
import com.fr.design.login.service.DesignerPassportManager;
@ -36,9 +35,6 @@ public class PluginLoginExecutor implements Executor {
@Override
public void run(Process<String> process) {
int uid = DesignerPassportManager.getInstance().login(username, password);
if (uid > 0) {
LoginWebBridge.getHelper().closeWindow();
}
result = String.valueOf(uid);
}
}

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

@ -2,19 +2,17 @@ package com.fr.design.jxbrowser;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.BasicPane;
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.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import com.fr.stable.os.OperatingSystem;
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.event.Observer;
import com.teamdev.jxbrowser.frame.Frame;
import com.teamdev.jxbrowser.js.JsObject;
@ -50,7 +48,7 @@ import static com.fr.design.ui.ModernUIConstants.WINDOW;
* @since 11.0
* Created on 2023-06-12
*/
public class JxUIPane<T> extends ModernUIPane<T> {
public class JxUIPane<T> extends BasicPane {
public static final ExecutorService DEFAULT_EXECUTOR =
Executors.newSingleThreadExecutor(new NamedThreadFactory("jx-simple", true));
@ -68,11 +66,9 @@ public class JxUIPane<T> extends ModernUIPane<T> {
private JxEngine jxEngine = JxEngine.getInstance();
private JxUIPane() {
super();
}
private JxUIPane(JxEngine jxEngine) {
super();
this.jxEngine = jxEngine;
}
@ -155,7 +151,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
*
* @param url 新的地址
*/
@Override
public void redirect(String url) {
browser.navigation().loadUrl(encodeWindowsPath(url));
}
@ -166,7 +161,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
* @param url 新的地址
* @param map 初始化参数
*/
@Override
public void redirect(String url, Map<String, String> map) {
setMap(map);
browser.navigation().loadUrl(encodeWindowsPath(url));
@ -186,7 +180,11 @@ public class JxUIPane<T> extends ModernUIPane<T> {
}
@Override
/**
* 更新数据到界面
*
* @param t 数据类
*/
public void populate(final T t) {
setInjectJsCallback(params -> {
executeJsObject(params.frame(), WINDOW + DOT + namespace)
@ -195,7 +193,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
});
}
@Override
@Nullable
public T update() {
if (browser.mainFrame().isPresent()) {
@ -283,7 +280,7 @@ public class JxUIPane<T> extends ModernUIPane<T> {
*
* @param <T> 参数
*/
public static class Builder<T> extends ModernUIPane.Builder<T> {
public static class Builder<T> {
private JxEngine jxEngine;
private String namespace;
private String variable;
@ -302,8 +299,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
private String html;
public Builder() {
// 为了兼容继承关系,但又不允许创建,用这个方式先处理一下
super((ModernUIPane<T>) null);
this.jxEngine = JxEngine.getInstance();
this.namespace = DEFAULT_NAMESPACE;
this.variable = DEFAULT_VARIABLE;
@ -342,24 +337,14 @@ public class JxUIPane<T> extends ModernUIPane<T> {
return this;
}
@Override
public Builder<T> prepareForV6(ScriptContextListener contextListener) {
return this;
}
@Override
public Builder<T> prepareForV6(LoadListener loadListener) {
return this;
}
@Override
public JxUIPane.Builder<T> prepareForV7(InjectJsCallback callback) {
prepare(callback);
return this;
}
@Override
public JxUIPane.Builder<T> prepareForV7(Class event, Observer listener) {
/**
* 注册一个监听器
*
* @param event 事件
* @param listener 监听器
* @return builder
*/
public JxUIPane.Builder<T> prepare(Class event, Observer listener) {
listenerPair = new Pair<>(event, listener);
return this;
}

6
designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java

@ -2,10 +2,8 @@ package com.fr.design.login;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.update.ui.dialog.UpdateMainDialog;
import com.fr.general.GeneralContext;
@ -47,10 +45,6 @@ public class DesignerLoginHelper {
}
public static void showLoginDialog(DesignerLoginSource source, Map<String, String> params, Window window) {
if (!SupportOSImpl.DESIGNER_LOGIN.support() || DesignerEnvManager.getEnvManager().isUseOldVersionLogin()) {
WebViewDlgHelper.createLoginDialog(window);
return;
}
boolean hasJxBrowser = true;
try {
Class.forName(JXBROWSER);

30
designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginBrowserExecutor.java

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

3
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java

@ -43,8 +43,7 @@ public class DesignerGuideHelper {
if (!DesignerLoginUtils.isOnline()
|| !SupportOSImpl.DESIGNER_LOGIN.support()
|| !FRContext.isChineseEnv()
|| DesignerPushUpdateManager.getInstance().isShouldPopUp()
|| DesignerEnvManager.getEnvManager().isUseOldVersionLogin()) {
|| DesignerPushUpdateManager.getInstance().isShouldPopUp()) {
return;
}
if (isActivatedForOneWeek()) {

18
designer-base/src/main/java/com/fr/design/login/message/NotificationActionType.java

@ -1,20 +1,15 @@
package com.fr.design.login.message;
import com.fr.config.ServerPreferenceConfig;
import com.fr.design.dialog.NotificationDialogAction;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.mainframe.BaseJForm;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.EastRegionContainerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.upm.UpmFinder;
import com.fr.design.utils.DesignUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.bridge.StableFactory;
import com.fr.stable.os.Arch;
import com.fr.stable.os.OperatingSystem;
/**
* @author Lanlan
@ -31,17 +26,10 @@ public enum NotificationActionType {
@Override
public void doClick() {
try {
if (Arch.getArch() == Arch.ARM || OperatingSystem.isLinux() || SupportOSImpl.MACOS_WEB_PLUGIN_MANAGEMENT.support()) {
DesignUtils.visitEnvServerByParameters("#management/plugin", null, null);
return;
}
if (ServerPreferenceConfig.getInstance().isUseOptimizedUPM() || SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()) {
UpmFinder.showUPMDialog();
} else {
WebViewDlgHelper.createPluginDialog();
}
} catch (Exception e) {
UpmFinder.showUPMDialog();
} catch (Throwable e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
DesignUtils.visitEnvServerByParameters("#management/plugin", null, null);
}
}
}),

32
designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java

@ -1,41 +1,31 @@
package com.fr.design.os.impl;
import com.fr.config.ServerPreferenceConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.jdk.JdkVersion;
import com.fr.design.upm.UpmFinder;
import com.fr.design.utils.DesignUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.os.Arch;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.os.OperatingSystem;
import com.fr.stable.os.support.OSBasedAction;
/**
* 插件管理窗口
*
* @author pengda
* @date 2019/10/9
*/
public class PMDialogAction implements OSBasedAction {
private static String PLUGIN_MANAGER_ROUTE = "#management/plugin";
@Override
public void execute(Object... objects) {
if(Arch.getArch() == Arch.ARM || OperatingSystem.isLinux() || SupportOSImpl.MACOS_WEB_PLUGIN_MANAGEMENT.support()){
DesignUtils.visitEnvServerByParameters( PLUGIN_MANAGER_ROUTE,null,null);
return;
}
if (checkUPMSupport()) {
if (OperatingSystem.isLinux()) {
DesignUtils.visitEnvServerByParameters(PLUGIN_MANAGER_ROUTE, null, null);
return;
}
try {
UpmFinder.showUPMDialog();
} else {
WebViewDlgHelper.createPluginDialog();
} catch (Throwable e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
DesignUtils.visitEnvServerByParameters(PLUGIN_MANAGER_ROUTE, null, null);
}
}
private boolean checkUPMSupport() {
return ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter()
//默认开启
|| DesignerEnvManager.getEnvManager().isUseNewPluginFirst();
}
}

55
designer-base/src/main/java/com/fr/design/os/impl/SupportOSImpl.java

@ -2,7 +2,6 @@ package com.fr.design.os.impl;
import com.fr.base.FRContext;
import com.fr.design.config.DesignerProperties;
import com.fr.design.jdk.JdkVersion;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.json.JSON;
@ -31,30 +30,33 @@ public enum SupportOSImpl implements SupportOS {
* 屏蔽登录入口
*/
BBS_USER_LOGIN_PANE {
public boolean support(){
return Arch.getArch() != Arch.ARM && DesignerProperties.getInstance().isSupportLoginEntry();
@Override
public boolean support() {
return DesignerProperties.getInstance().isSupportLoginEntry();
}
},
/**
* Linux系统屏蔽透明度
*/
OPACITY{
public boolean support(){
OPACITY {
@Override
public boolean support() {
return !OperatingSystem.isLinux();
}
},
/**
* Linux系统屏蔽FineUI选项
*/
FINEUI{
public boolean support(){
FINEUI {
@Override
public boolean support() {
return !OperatingSystem.isLinux();
}
},
/**
* 自动更新推送
*/
AUTOPUSHUPDATE{
AUTOPUSHUPDATE {
@Override
public boolean support() {
boolean isLocalEnv = WorkContext.getCurrent().isLocal();
@ -75,7 +77,7 @@ public enum SupportOSImpl implements SupportOS {
/**
* BBS窗口
*/
BBSDIALOG{
BBSDIALOG {
@Override
public boolean support() {
return FRContext.isChineseEnv() && !OperatingSystem.isMacos() && Arch.getArch() != Arch.ARM;
@ -117,7 +119,6 @@ public enum SupportOSImpl implements SupportOS {
/**
* 原生文件选择器弹窗
* https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8019464 mac下原生弹窗国际化设置无效,jdk11中有修复
*
*/
NATIVE_CHOOSER {
@Override
@ -133,23 +134,7 @@ public enum SupportOSImpl implements SupportOS {
}
},
MACOS_NEW_PLUGIN_MANAGEMENT {
@Override
public boolean support() {
return JdkVersion.GE_9.support() && OperatingSystem.isMacos() && getMacOsVersion() < BIG_SUR_VERSION_NUMBER;
}
},
MACOS_WEB_PLUGIN_MANAGEMENT {
@Override
public boolean support() {
return JdkVersion.GE_9.support() && OperatingSystem.isMacos() && getMacOsVersion() >= BIG_SUR_VERSION_NUMBER;
}
},
OLD_STYLE_CHOOSER {
@Override
public boolean support() {
boolean javafxExist = true;
@ -196,23 +181,9 @@ public enum SupportOSImpl implements SupportOS {
DESIGNER_LOGIN {
@Override
public boolean support() {
if (OperatingSystem.isLinux()) {
return false;
}
return !OperatingSystem.isMacos() || getMacOsVersion() < BIG_SUR_VERSION_NUMBER;
}
};
private static final int BIG_SUR_VERSION_NUMBER = 16;
protected int getMacOsVersion() {
String version = System.getProperty("os.version");
String[] versionSlice = version.split("\\.");
try {
return Integer.parseInt(versionSlice[1]);
} catch (Exception ignored) {
return 0;
return !OperatingSystem.isLinux();
}
}
}

91
designer-base/src/main/java/com/fr/design/ui/Assistant.java

@ -1,91 +0,0 @@
package com.fr.design.ui;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserContext;
import com.teamdev.jxbrowser.chromium.BrowserPreferences;
import com.teamdev.jxbrowser.chromium.ProtocolService;
import com.teamdev.jxbrowser.chromium.URLResponse;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-07
*/
public class Assistant {
public static void addChromiumSwitches(String... switches) {
List<String> list = BrowserPreferences.getChromiumSwitches();
Collections.addAll(list, switches);
BrowserPreferences.setChromiumSwitches((list.toArray(new String[0])));
}
public static URLResponse inputStream2Response(InputStream inputStream, String filePath) throws Exception {
URLResponse response = new URLResponse();
DataInputStream stream = new DataInputStream(inputStream);
byte[] data = new byte[stream.available()];
stream.readFully(data);
response.setData(data);
String mimeType = getMimeType(filePath);
response.getHeaders().setHeader("Content-Type", mimeType);
return response;
}
private static String getMimeType(String path) {
if (StringUtils.isBlank(path)) {
return "text/html";
}
if (path.endsWith(".html")) {
return "text/html";
}
if (path.endsWith(".css")) {
return "text/css";
}
if (path.endsWith(".js")) {
return "text/javascript";
}
if (path.endsWith(".svg")) {
return "image/svg+xml";
}
// upm 文件夹中的图片如果返回 Content-type 为 image/png 时会显示异常
if (path.endsWith(".png") && !path.contains("/upm")) {
return "image/png";
}
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();
try {
return Files.probeContentType(file);
} catch (IOException e) {
return "text/html";
}
}
public static void setEmbProtocolHandler(Browser browser, EmbProtocolHandler handler) {
BrowserContext browserContext = browser.getContext();
ProtocolService protocolService = browserContext.getProtocolService();
// 支持读取jar包中文件的自定义协议————emb:/com/fr/design/images/bbs.png
protocolService.setProtocolHandler("emb", handler);
protocolService.setProtocolHandler("file", handler);
}
}

135
designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java

@ -1,135 +0,0 @@
package com.fr.design.ui;
import com.fr.base.TemplateUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.codec.net.URLCodec;
import com.fr.third.org.apache.commons.io.FileUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.web.struct.AssembleComponent;
import com.fr.web.struct.AtomBuilder;
import com.fr.web.struct.PathGroup;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
import com.teamdev.jxbrowser.chromium.ProtocolHandler;
import com.teamdev.jxbrowser.chromium.URLRequest;
import com.teamdev.jxbrowser.chromium.URLResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-07
*/
public class EmbProtocolHandler implements ProtocolHandler {
private AssembleComponent component;
private Map<String, String> map;
public EmbProtocolHandler() {
}
public EmbProtocolHandler(AssembleComponent component) {
this.component = component;
}
public EmbProtocolHandler(AssembleComponent component, Map<String, String> map) {
this.component = component;
this.map = map;
}
public EmbProtocolHandler(Map<String, String> map) {
this.map = map;
}
@Override
public URLResponse onRequest(URLRequest req) {
InputStream inputStream = null;
try {
String path = req.getURL();
if (path.startsWith("file:")) {
String url = new URLCodec().decode(path);
String filePath = TemplateUtils.renderParameter4Tpl(url, map);
File file = new File(URI.create(filePath).getPath());
inputStream = IOUtils.readResource(file.getAbsolutePath());
String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8);
text = TemplateUtils.renderParameter4Tpl(text, map);
return Assistant.inputStream2Response(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), path);
} else if (path.startsWith("emb:dynamic")) {
URLResponse response = new URLResponse();
response.setData(htmlText(map).getBytes());
response.getHeaders().setHeader("Content-Type", "text/html");
return response;
} else {
int index = path.indexOf("=");
if (index > 0) {
path = path.substring(index + 1);
} else {
path = path.substring(4);
}
inputStream = IOUtils.readResource(path);
if (path.endsWith(".html")) {
String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8);
text = TemplateUtils.renderParameter4Tpl(text, map);
return Assistant.inputStream2Response(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), path);
}
return Assistant.inputStream2Response(inputStream, path);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
return null;
}
private String htmlText(Map<String, String> map) {
PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component);
StylePath[] stylePaths = pathGroup.toStylePathGroup();
StringBuilder styleText = new StringBuilder();
for (StylePath path : stylePaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
styleText.append("<link rel=\"stylesheet\" href=\"emb:");
styleText.append(path.toFilePath());
styleText.append("\"/>");
}
}
String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString());
ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup();
StringBuilder scriptText = new StringBuilder();
for (ScriptPath path : scriptPaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
scriptText.append("<script src=\"emb:");
scriptText.append(path.toFilePath());
scriptText.append("\"></script>");
}
}
result = result.replaceAll("##script##", scriptText.toString());
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
result = result.replaceAll("\\$\\{" + key + "}", value);
}
}
return result;
}
}

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

@ -1,364 +0,0 @@
package com.fr.design.ui;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.BasicPane;
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.compatible.BuilderDiff;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserType;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;
import com.teamdev.jxbrowser.event.Observer;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Map;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-04
* 用于加载html5的Swing容器可以在设计选项设置中打开调试窗口示例可查看com.fr.design.ui.ModernUIPaneTest
* @see {@link com.fr.design.jxbrowser.JxUIPane}
* @deprecated 主要用于jxbrowser6将在下个版本删除
*/
@Deprecated
public class ModernUIPane<T> extends BasicPane {
private Browser browser;
private String namespace = "Pool";
private String variable = "data";
private String expression = "update()";
private ModernUIPane(BrowserType browserType) {
initialize(browserType);
}
protected ModernUIPane() {
}
private void initialize(BrowserType browserType) {
if (browser == null) {
setLayout(new BorderLayout());
Assistant.addChromiumSwitches("--disable-google-traffic");
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(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showDebuggerDialog();
}
});
reloadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
browser.reloadIgnoringCache();
}
});
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.getWindowAncestor(ModernUIPane.this).setVisible(false);
}
});
Assistant.addChromiumSwitches("--remote-debugging-port=9222");
initializeBrowser(browserType);
add(new BrowserView(browser), BorderLayout.CENTER);
} else {
initializeBrowser(browserType);
add(new BrowserView(browser), BorderLayout.CENTER);
}
}
}
private void showDebuggerDialog() {
JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this));
Browser debugger = new Browser();
BrowserView debuggerView = new BrowserView(debugger);
dialog.add(debuggerView, BorderLayout.CENTER);
dialog.setSize(new Dimension(800, 400));
GUICoreUtils.centerWindow(dialog);
dialog.setVisible(true);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
debugger.loadURL(browser.getRemoteDebuggingURL());
}
private void initializeBrowser(BrowserType browserType) {
browser = new Browser(browserType);
// 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的
browser.addScriptContextListener(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
event.getBrowser().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace));
}
});
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
*/
public void redirect(String url) {
browser.loadURL(url);
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
* @param map 初始化参数
*/
public void redirect(String url, Map<String, String> map) {
Assistant.setEmbProtocolHandler(browser, new EmbProtocolHandler(map));
browser.loadURL(url);
}
@Override
protected String title4PopupWindow() {
return "Modern";
}
public void populate(final T t) {
browser.addScriptContextListener(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue ns = event.getBrowser().executeJavaScriptAndReturnValue("window." + namespace);
ns.asObject().setProperty(variable, t);
}
});
}
public T update() {
JSValue jsValue = browser.executeJavaScriptAndReturnValue("window." + namespace + "." + expression);
if (jsValue.isObject()) {
return (T) jsValue.asJavaObject();
}
return null;
}
public void disposeBrowser() {
if (browser != null) {
browser.dispose();
browser = null;
}
}
public void clearCache() {
if (browser != null) {
browser.getCacheStorage().clearCache();
File file = new File(browser.getContext().getCacheDir());
if (file.exists()) {
file.delete();
}
}
}
public void executeJavaScript(String javaScript) {
if (browser != null) {
browser.executeJavaScript(javaScript);
}
}
public JSValue executeJavaScriptAndReturnValue(String javaScript) {
if (browser != null) {
return browser.executeJavaScriptAndReturnValue(javaScript);
}
return null;
}
/**
* ModernUIPane 建造者
*
* @param <T>
*/
public static class Builder<T> implements BuilderDiff<T> {
private ModernUIPane<T> pane;
public Builder() {
this(BrowserType.HEAVYWEIGHT);
}
public Builder(BrowserType browserType) {
this.pane = new ModernUIPane<>(browserType);
}
public Builder(ModernUIPane<T> pane) {
this.pane = pane;
}
public Builder<T> prepare(ScriptContextListener contextListener) {
pane.browser.addScriptContextListener(contextListener);
return this;
}
public Builder<T> prepare(LoadListener loadListener) {
pane.browser.addLoadListener(loadListener);
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public Builder<T> withEMB(final String path) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler());
pane.browser.loadURL("emb:" + path);
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public Builder<T> withEMB(final String path, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(map));
pane.browser.loadURL("emb:" + path);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public Builder<T> withURL(final String url) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler());
pane.browser.loadURL(url);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public Builder<T> withURL(final String url, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(map));
pane.browser.loadURL(url);
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public Builder<T> withComponent(AssembleComponent component) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component));
pane.browser.loadURL("emb:dynamic");
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public Builder<T> withComponent(AssembleComponent component, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component, map));
pane.browser.loadURL("emb:dynamic");
return this;
}
/**
* 加载html文本内容
*
* @param html 要加载html文本内容
*/
public Builder<T> withHTML(String html) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler());
pane.browser.loadHTML(html);
return this;
}
/**
* 设置该前端页面做数据交换所使用的对象
*
* @param namespace 对象名
*/
public Builder<T> namespace(String namespace) {
pane.namespace = namespace;
return this;
}
/**
* java端往js端传数据时使用的变量名字
*
* @param name 变量的名字
*/
public Builder<T> variable(String name) {
pane.variable = name;
return this;
}
/**
* js端往java端传数据时执行的函数表达式
*
* @param expression 函数表达式
*/
public Builder<T> expression(String expression) {
pane.expression = expression;
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;
}
@Override
public Builder<T> prepareForV7(Class event, Observer listener) {
// do nothing
return this;
}
public ModernUIPane<T> build() {
return pane;
}
}
}

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

@ -1,55 +0,0 @@
package com.fr.design.ui.compatible;
import com.fr.design.jxbrowser.JxUIPane;
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;
import com.teamdev.jxbrowser.event.Observer;
/**
* 封装jxbrwoser v6/v7的构建方式的差异
*
* @author hades
* @see {@link JxUIPane}
* @since 10.0
* Created on 2021/6/13
* @deprecated 6在下个版本弃用
*/
@Deprecated
public interface BuilderDiff<T> {
/**
* v6准备工作
*
* @param contextListener 上下文监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV6(ScriptContextListener contextListener);
/**
* v6准备工作
*
* @param loadListener 加载监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV6(LoadListener loadListener);
/**
* v7准备工作
*
* @param callback 注入js回调器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV7(InjectJsCallback callback);
/**
* v7准备工作
*
* @param event 事件
* @param listener 监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV7(Class event, Observer listener);
}

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

@ -1,45 +0,0 @@
package com.fr.design.ui.compatible;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.ui.ModernUIPane;
/**
* 根据版本选择构造器
*
* @author hades
* @see {@link JxUIPane}
* @since 10.0
* Created on 2021/6/13
* @deprecated 6在下个版本弃用
*/
public class ModernUIPaneFactory {
/**
* 获取一个 JxBrowser pane 的构造器
*
* @param <T> 参数
* @return 构造器
*/
public static <T> ModernUIPane.Builder<T> modernUIPaneBuilder() {
if (isV7()) {
return new JxUIPane.Builder<>();
} else {
return new ModernUIPane.Builder<>();
}
}
/**
* 判断 JxBrowser 版本是否在7或之上
*
* @return 是否7或之上
*/
public static boolean isV7() {
boolean jxBrowserV7 = true;
try {
Class.forName("com.teamdev.jxbrowser.net.Scheme");
} catch (ClassNotFoundException e) {
jxBrowserV7 = false;
}
return jxBrowserV7;
}
}

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

@ -1,515 +0,0 @@
package com.fr.design.upm;
import com.fr.config.ServerPreferenceConfig;
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.gui.ifilechooser.FileChooserArgs;
import com.fr.design.gui.ifilechooser.FileChooserFactory;
import com.fr.design.gui.ifilechooser.FileChooserProvider;
import com.fr.design.gui.ifilechooser.FileSelectionMode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.upm.event.DownloadEvent;
import com.fr.design.upm.exec.UpmBrowserExecutor;
import com.fr.design.upm.task.UpmTaskWorker;
import com.fr.design.utils.BrowseUtils;
import com.fr.event.EventDispatcher;
import com.fr.general.GeneralUtils;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
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.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSArray;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-12
* 桥接Java和JavaScript的类
* @deprecated 用于jxbrowser6下版本删除
*/
@Deprecated
public class UpmBridge {
public static UpmBridge getBridge(Browser browser) {
return new UpmBridge(browser);
}
private JSObject window;
private UpmBridge(Browser browser) {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
}
protected UpmBridge() {
}
/**
* 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
public void update(final JSFunction callback) {
callback.invoke(window, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start"));
try {
UpmResourceLoader.INSTANCE.download();
UpmResourceLoader.INSTANCE.install();
callback.invoke(window, "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(window, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error"));
}
}
/**
* 下载并安装插件管理中心的资源文件
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
public void startDownload(final JSFunction callback) {
callback.invoke(window, "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(window, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success"));
EventDispatcher.fire(DownloadEvent.SUCCESS, "success");
} catch (Exception e) {
callback.invoke(window, "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
public String getVersion() {
return ServerPreferenceConfig.getInstance().getOptimizedUPMVersion();
}
@JSBridge
public String i18nText(String key) {
return Toolkit.i18nText(key);
}
@JSBridge
public void closeWindow() {
UIUtil.invokeLaterIfNeeded(UpmFinder::closeWindow);
}
@JSBridge
public boolean isDesigner() {
return true;
}
@JSBridge
public void getPackInfo(final JSFunction callback) {
callback.invoke(window, StringUtils.EMPTY);
}
@JSBridge
public void getPluginPrefix(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginPrefixExecutor());
task.execute();
}
/**
* 在线获取插件分类
*
* @param callback 回调函数
*/
@JSBridge
public void getPluginCategories(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginCategoriesExecutor());
task.execute();
}
/**
* 根据条件获取在线插件
*
* @param info 插件信息
* @param callback 回调函数
*/
@JSBridge
public void getPluginFromStoreNew(String info, final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginFromStoreExecutor(new JSONObject(info)));
task.execute();
}
/**
* 已安装插件检查更新
*/
@JSBridge
public void readUpdateOnline(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new ReadUpdateOnlineExecutor());
task.execute();
}
/**
* 获取已经安装的插件的数组
*/
@JSBridge
public void getInstalledPlugins(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetInstalledPluginsExecutor());
task.execute();
}
/**
* 从插件服务器上更新选中的插件
*
* @param pluginIDs 插件集合
*/
@JSBridge
public void updatePluginOnline(Object pluginIDs, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
List<PluginMarker> pluginMarkerList = new ArrayList<>();
if (pluginIDs instanceof String) {
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginIDs.toString()));
} else if (pluginIDs instanceof JSArray) {
JSArray pluginInfos = (JSArray) pluginIDs;
for (int i = 0, len = pluginInfos.length(); i < len; i++) {
String value = pluginInfos.get(i).asString().getValue();
pluginMarkerList.add(PluginUtils.createPluginMarker(value));
}
}
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
/**
* 搜索在线插件
*
* @param keyword 关键字
*/
@JSBridge
public void searchPlugin(String keyword, final JSFunction callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new SearchOnlineExecutor(keyword));
worker.execute();
}
/**
* 从磁盘上选择插件安装包进行安装
*
* @param filePath 插件包的路径
*/
@JSBridge
public void installPluginFromDisk(final String filePath, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
File file = new File(filePath);
PluginOperateUtils.installPluginFromDisk(file, jsCallback);
}
/**
* 卸载当前选中的插件
*
* @param pluginInfo 插件信息
*/
@JSBridge
public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
}
/**
* 从插件服务器上安装插件
*
* @param pluginInfo 插件的ID
* @param callback 回调函数
*/
@JSBridge
public void installPluginOnline(final String pluginInfo, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行插件升级
*
* @param filePath 插件包的路径
*/
public void updatePluginFromDisk(String filePath, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
File file = new File(filePath);
PluginOperateUtils.updatePluginFromDisk(file, jsCallback);
}
/**
* 修改选中的插件的活跃状态
*
* @param pluginID 插件ID
*/
@JSBridge
public void setPluginActive(String pluginID, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 批量修改选中的插件的活跃状态
*
* @param pluginIDs 要处理的插件ID
* @param callback 回调函数
*/
@JSBridge
public void setAllPluginActive(JSArray pluginIDs, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
List<String> list = new ArrayList<>();
int len = pluginIDs.length();
for (int i = 0; i < len; i++) {
list.add(pluginIDs.get(i).asString().getValue());
}
PluginOperateUtils.setPluginActive(list, jsCallback);
}
/**
* 选择文件对话框
*
* @return 选择的文件的路径
*/
@JSBridge
public String showFileChooser() {
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param filter 文件的后缀
* @return 选择的文件的路径
* 这里换用JFileChooser会卡死,不知道为什么
*/
@JSBridge
public String showFileChooserWithFilter(final String des, final String filter) {
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() {
@Override
public String call() {
FileChooserProvider fileChooserProvider = FileChooserFactory.createFileChooser(
FileChooserArgs.newBuilder().
setFileSelectionMode(FileSelectionMode.FILE).
setFilter(des, filter).build());
int result = fileChooserProvider.showDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooserProvider.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
public String showFileChooserWithFilters(final String des, final Object args) {
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() {
@Override
public String call() {
JFileChooser fileChooser = new JFileChooser();
List<String> filterList = new ArrayList<>();
if (args instanceof String) {
filterList.add(GeneralUtils.objectToString(args));
} else if (args instanceof JSArray) {
JSArray array = (JSArray) args;
for (int i = 0, len = array.length(); i < len; i++) {
filterList.add(array.get(i).getStringValue());
}
}
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
public String getLoginInfo(final JSFunction callback) {
registerLoginInfo(callback);
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
/**
* 系统登录注册
*
* @param callback 回调函数
*/
@JSBridge
public void registerLoginInfo(final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
String username = DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
if (StringUtils.isEmpty(username)) {
jsCallback.execute(StringUtils.EMPTY);
} else {
jsCallback.execute(username);
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @param callback 回调函数
*/
@JSBridge
public void defaultLogin(String username, String password, final JSFunction callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new PluginLoginExecutor(username, password));
worker.execute();
}
/**
* 清除用户信息
*/
@JSBridge
public void clearUserInfo() {
}
/**
* 打开论坛消息界面
*/
@JSBridge
public void getPriviteMessage() {
try {
LocaleMark<String> spaceMark = LocaleCenter.getMark(BbsSpaceMark.class);
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(spaceMark.getValue());
BrowseUtils.browser(ssoUrl);
} catch (Exception exp) {
FineLoggerFactory.getLogger().info(exp.getMessage());
}
}
/**
* 忘记密码
*/
@JSBridge
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 立即注册
*/
@JSBridge
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 使用系统浏览器打开网页
*
* @param url 要打开的网页
*/
@JSBridge
public void openShopUrlAtWebBrowser(String url) {
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
}

122
designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java

@ -1,5 +1,6 @@
package com.fr.design.upm;
import com.fr.config.ServerPreferenceConfig;
import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.bridge.exec.JSBridge;
@ -13,13 +14,25 @@ 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.gui.ifilechooser.FileChooserArgs;
import com.fr.design.gui.ifilechooser.FileChooserFactory;
import com.fr.design.gui.ifilechooser.FileChooserProvider;
import com.fr.design.gui.ifilechooser.FileSelectionMode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.ui.util.UIUtil;
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.design.utils.BrowseUtils;
import com.fr.event.EventDispatcher;
import com.fr.general.GeneralUtils;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
@ -29,24 +42,29 @@ import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.js.internal.JsArrayImpl;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-12
* 桥接Java和JavaScript的类
*
* @author richie
* @since 10.0
* Created on 2019-04-12
*/
@JsAccessible
public class UpmBridgeV7 extends UpmBridge {
public class UpmBridgeV7 {
public static UpmBridgeV7 getBridge(JsObject jsObject) {
return new UpmBridgeV7(jsObject);
@ -117,30 +135,40 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public String getVersion() {
return super.getVersion();
return ServerPreferenceConfig.getInstance().getOptimizedUPMVersion();
}
/**
* 国际化
*
* @param key 国际化key
* @return 国际化文本
*/
@JSBridge
@JsAccessible
@Override
public String i18nText(String key) {
return super.i18nText(key);
return Toolkit.i18nText(key);
}
/**
* 关闭窗口
*/
@JSBridge
@JsAccessible
@Override
public void closeWindow() {
super.closeWindow();
UIUtil.invokeLaterIfNeeded(UpmFinder::closeWindow);
}
/**
* 是否设计器
*
* @return 是否设计器
*/
@JSBridge
@JsAccessible
@Override
public boolean isDesigner() {
return super.isDesigner();
return true;
}
@JSBridge
@ -326,9 +354,8 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public String showFileChooser() {
return super.showFileChooser();
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
@ -341,9 +368,28 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public String showFileChooserWithFilter(final String des, final String filter) {
return super.showFileChooserWithFilter(des, filter);
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() {
@Override
public String call() {
FileChooserProvider fileChooserProvider = FileChooserFactory.createFileChooser(
FileChooserArgs.newBuilder().
setFileSelectionMode(FileSelectionMode.FILE).
setFilter(des, filter).build());
int result = fileChooserProvider.showDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooserProvider.getSelectedFile().getAbsolutePath();
}
return null;
}
});
SwingUtilities.invokeLater(future);
try {
return future.get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
/**
@ -469,9 +515,7 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JsAccessible
@JSBridge
@Override
public void clearUserInfo() {
super.clearUserInfo();
}
/**
@ -479,9 +523,14 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void getPriviteMessage() {
super.getPriviteMessage();
try {
LocaleMark<String> spaceMark = LocaleCenter.getMark(BbsSpaceMark.class);
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(spaceMark.getValue());
BrowseUtils.browser(ssoUrl);
} catch (Exception exp) {
FineLoggerFactory.getLogger().info(exp.getMessage());
}
}
/**
@ -489,9 +538,13 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void forgetHref() {
super.forgetHref();
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
@ -499,9 +552,13 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void registerHref() {
super.registerHref();
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
@ -511,8 +568,21 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void openShopUrlAtWebBrowser(String url) {
super.openShopUrlAtWebBrowser(url);
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
}

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

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

4
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/ComposedNativeBridges.java

@ -1,6 +1,5 @@
package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
/**
@ -9,15 +8,12 @@ import com.teamdev.jxbrowser.js.JsAccessible;
* Created by Starryi on 2021/12/20
*/
public class ComposedNativeBridges {
@JSAccessible
@JsAccessible
public final Object Browser;
@JSAccessible
@JsAccessible
public final Object Auth;
@JSAccessible
@JsAccessible
public final Object Product;

3
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeAuthBridge.java

@ -5,7 +5,6 @@ import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.login.DesignerLoginHelper;
import com.fr.design.login.DesignerLoginSource;
import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import java.awt.Window;
@ -17,14 +16,12 @@ import java.util.HashMap;
* Created by Starryi on 2021/12/20
*/
public class NativeAuthBridge {
@JSAccessible
@JsAccessible
@JSBridge
public String getLoginUsername() {
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
@JSAccessible
@JsAccessible
@JSBridge
public void goLogin() {

2
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeBrowserBridge.java

@ -2,7 +2,6 @@ package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import java.awt.Window;
@ -14,7 +13,6 @@ import java.awt.Window;
*/
public class NativeBrowserBridge {
@JSAccessible
@JsAccessible
@JSBridge
public void dispose() {

21
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java

@ -20,7 +20,6 @@ import com.fr.form.share.bean.OnlineShareWidget;
import com.fr.form.share.group.DefaultShareGroupManager;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import javax.swing.JOptionPane;
@ -55,13 +54,12 @@ public class NativeProductBridge {
this.window = window;
}
@JSAccessible
@JsAccessible
@JSBridge
public boolean isProductDownloaded(String uuid) {
for (Group group : DefaultShareGroupManager.getInstance().getAllGroup()) {
SharableWidgetProvider[] widgetProviderList = group.getAllBindInfoList();
for (SharableWidgetProvider widget: widgetProviderList) {
for (SharableWidgetProvider widget : widgetProviderList) {
if (StringUtils.equals(uuid, widget.getId())) {
return true;
}
@ -70,7 +68,6 @@ public class NativeProductBridge {
return false;
}
@JSAccessible
@JsAccessible
@JSBridge
public void addProductDownloadTaskStartListener(String json, Object function) {
@ -91,7 +88,6 @@ public class NativeProductBridge {
}
@JSAccessible
@JsAccessible
@JSBridge
public void removeProductDownloadTaskStartListener(String json, Object function) {
@ -110,7 +106,6 @@ public class NativeProductBridge {
downloadTaskGetters.put(uuid, startListeners);
}
@JSAccessible
@JsAccessible
@JSBridge
public Object getExecutingProductDownloadTask(String json) {
@ -128,7 +123,6 @@ public class NativeProductBridge {
return task;
}
@JSAccessible
@JsAccessible
@JSBridge
public Object createProductDownloadTask(String json) {
@ -155,7 +149,6 @@ public class NativeProductBridge {
}
}
@JSAccessible
@JsAccessible
@JSBridge
public void addThemeDownloadTaskStartListener(String themePath, Object function) {
@ -167,7 +160,6 @@ public class NativeProductBridge {
themeDownloadTaskStartListeners.put(themePath, startListeners);
}
@JSAccessible
@JsAccessible
@JSBridge
public void removeThemeDownloadTaskStartListener(String themePath, Object function) {
@ -179,7 +171,6 @@ public class NativeProductBridge {
themeDownloadTaskStartListeners.put(themePath, startListeners);
}
@JSAccessible
@JsAccessible
@JSBridge
public Object getExecutingThemeDownloadTask(String themePath) {
@ -190,7 +181,6 @@ public class NativeProductBridge {
return task;
}
@JSAccessible
@JsAccessible
@JSBridge
public Object createTemplateThemeDownloadTask(String themePath) {
@ -236,7 +226,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -256,7 +245,7 @@ public class NativeProductBridge {
"",
FineJOptionPane.OK_CANCEL_OPTION
);
allowedDownload = result == JOptionPane.OK_OPTION;
allowedDownload = result == JOptionPane.OK_OPTION;
}
if (allowedDownload) {
fireStartEvent(null);
@ -268,7 +257,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -341,7 +329,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -370,7 +357,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -412,6 +398,7 @@ public class NativeProductBridge {
private final NativeProductBridge env;
private final String themePath;
private final TemplateThemeInstallation action;
public TemplateThemeInstallationTask(NativeProductBridge env, Object window, String themePath) {
super(window);
this.env = env;
@ -436,7 +423,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -454,7 +440,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override

5
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeTaskBridge.java

@ -3,7 +3,6 @@ package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.mainframe.share.mini.MiniShopNativeTask;
import com.fr.design.mainframe.share.mini.MiniShopNativeTaskManager;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import java.util.HashSet;
@ -32,21 +31,18 @@ public class NativeTaskBridge implements MiniShopNativeTask {
}
@JSBridge
@JSAccessible
@JsAccessible
public void addStatusCallback(Object cb) {
this.statusCbs.add(cb);
}
@JSBridge
@JSAccessible
@JsAccessible
public void removeStatusCallback(Object cb) {
this.statusCbs.remove(cb);
}
@JSBridge
@JSAccessible
@JsAccessible
@Override
public void execute() {
@ -56,7 +52,6 @@ public class NativeTaskBridge implements MiniShopNativeTask {
}
@JSBridge
@JSAccessible
@JsAccessible
@Override
public void cancel() {

22
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/SafeJSFunctionInvoker.java

@ -1,7 +1,5 @@
package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
@ -16,29 +14,15 @@ public class SafeJSFunctionInvoker {
public static void invoke(Collection<Object> functions, Object instance, Object... args) {
if (functions != null) {
for (Object function: functions) {
for (Object function : functions) {
invoke(function, instance, args);
}
}
}
public static void invoke(Object function, Object instance, Object... args) {
if (function != null) {
if (function instanceof JSFunction && instance instanceof JSObject) {
invokeV6((JSFunction) function, (JSObject) instance, args);
} else if (function instanceof JsFunction && instance instanceof JsObject) {
invokeV7((JsFunction) function, (JsObject) instance, args);
}
}
}
private static void invokeV6(JSFunction function, JSObject instance, Object... args) {
if (!function.getContext().isDisposed()) {
function.invoke(instance, args);
if (function instanceof JsFunction && instance instanceof JsObject) {
((JsFunction) function).invoke((JsObject) instance, args);
}
}
private static void invokeV7(JsFunction function, JsObject instance, Object... args) {
function.invoke(instance, args);
}
}

5
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/cell/model/PluginModel.java

@ -1,8 +1,8 @@
package com.fr.design.mainframe.alphafine.cell.model;
import com.fr.design.actions.help.alphafine.AlphaFineCloudConstants;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.upm.UpmFinder;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
@ -112,7 +112,8 @@ public class PluginModel extends AlphaCellModel {
* 方便埋点
*/
private void openPluginStore(String name) {
WebViewDlgHelper.createPluginDialog(name);
// 适配
UpmFinder.showUPMDialog();
}
@Override

46
designer-realize/src/main/java/com/fr/design/mainframe/bbs/BBSDialog.java

@ -1,12 +1,11 @@
package com.fr.design.mainframe.bbs;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.PluginWebBridge;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.general.CloudCenter;
import com.fr.stable.StringUtils;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
@ -18,9 +17,14 @@ import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import javax.swing.JDialog;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Frame;
import java.io.IOException;
import java.net.URI;
/**
* @author richie
@ -99,7 +103,7 @@ public class BBSDialog extends UIDialog {
if (ComparatorUtils.equals(newValue, url) || ComparatorUtils.equals(newValue, CloudCenter.getInstance().acquireUrlByKind("bbs.mobile"))) {
return;
}
PluginWebBridge.getHelper().openUrlAtLocalWebBrowser(eng, newValue);
openUrlAtLocalWebBrowser(newValue);
}
});
eng.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
@ -116,6 +120,34 @@ public class BBSDialog extends UIDialog {
});
}
/**
* 在本地浏览器里打开url
*
* @param eng web引擎
* @param url 要打开的地址
*/
public void openUrlAtLocalWebBrowser(String url) {
if (StringUtils.isBlank(url)) {
return;
}
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (IOException e) {
//此为无法获取系统默认浏览器
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* 提供给web页面调用的关闭窗口
*/

73
designer-realize/src/main/java/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java

@ -2,16 +2,12 @@ package com.fr.design.report.freeze;
import com.fine.theme.utils.FineUIStyle;
import com.fr.base.FRContext;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.gui.frpane.FineTabbedPane;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.page.ReportPageAttrProvider;
import com.fr.stable.ColumnRow;
@ -19,12 +15,11 @@ import com.fr.stable.FT;
import com.fr.stable.bridge.StableFactory;
import com.fr.workspace.WorkContext;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.BorderLayout;
import java.awt.Color;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
@ -701,17 +696,6 @@ public class RepeatAndFreezeSettingPane extends BasicPane {
|| this.useRepeatFinisCCheckBox.isSelected();
}
/**
* 给内部的重复与冻结选项添加指定的边框
*
* @param jPanel 重复或冻结对应的界面
* @param title 边框的文字
*/
public static void addBorder(JPanel jPanel, String title) {
jPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createMatteBorder(1,0,0,0, UIConstants.TITLED_BORDER_COLOR), title));
jPanel.setPreferredSize(new Dimension(REPEAT_AND_FROZEN_WIDTH,REPEAT_AND_FROZEN_HEIGHT));
}
protected void updateRowPane(ReportPageAttrProvider attribute) {
// 重复标题行
int titleFrom = valid(useRepeatTitleRCheckBox, this.repeatTitleRowPane.updateBean().getFrom());
@ -766,55 +750,4 @@ public class RepeatAndFreezeSettingPane extends BasicPane {
return null;
}
private BoxCenterAligmentPane getURLActionLabel(final String text) {
ActionLabel actionLabel = new ActionLabel(text);
actionLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
//Desktop.getDesktop().browse(new URI(url));
WebViewDlgHelper.createPluginDialog();
RepeatAndFreezeSettingPane.this.getTopLevelAncestor().setVisible(false);
} catch (Exception exp) {
}
}
});
return new BoxCenterAligmentPane(actionLabel);
}
class BoxCenterAligmentPane extends JPanel {
private UILabel textLabel;
public BoxCenterAligmentPane(String text) {
this(new UILabel(text));
}
public BoxCenterAligmentPane(UILabel label) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel centerPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
this.add(centerPane, BorderLayout.CENTER);
UILabel label1 = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Form_Frozen_Tip"));
label1.setForeground(new Color(255, 0, 0));
UILabel label2 = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Form_Forzen_Speed"));
label2.setForeground(new Color(255, 0, 0));
this.textLabel = label;
centerPane.add(label1);
centerPane.add(textLabel);
centerPane.add(label2);
}
public void setFont(Font font) {
super.setFont(font);
if (textLabel != null) {
textLabel.setFont(font);
}
}
}
}

11
designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java

@ -1,5 +1,6 @@
package com.fr.design.share.ui.generate;
import com.fanruan.product.ProductConstants;
import com.fr.design.DesignerEnvManager;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicDialog;
@ -7,7 +8,6 @@ import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.event.ChangeEvent;
import com.fr.design.event.ChangeListener;
import com.fr.design.extra.LoginWebBridge;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.LazyComboBox;
@ -37,10 +37,10 @@ import com.fr.design.share.effect.EffectItemGroup;
import com.fr.design.share.utils.ShareDialogUtils;
import com.fr.file.FileCommonUtils;
import com.fr.form.share.DefaultSharableWidget;
import com.fr.form.share.Group;
import com.fr.form.share.bean.StyleThemeBean;
import com.fr.form.share.constants.ShareComponentConstants;
import com.fr.form.share.group.DefaultShareGroupManager;
import com.fr.form.share.Group;
import com.fr.json.JSON;
import com.fr.json.JSONArray;
import com.fr.json.JSONFactory;
@ -48,14 +48,9 @@ import com.fr.plugin.context.PluginContext;
import com.fr.plugin.manage.PluginFilter;
import com.fr.plugin.manage.PluginManager;
import com.fr.stable.ArrayUtils;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import com.fr.stable.pinyin.PinyinHelper;
import java.awt.TextField;
import java.util.Collections;
import java.util.HashMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
@ -88,6 +83,7 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
@ -505,7 +501,6 @@ public class ShareMainPane extends JPanel {
unLoginLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
LoginWebBridge.getHelper().setUILabel(hidden);
Dialog shareDialog = ShareDialogUtils.getInstance().getShareDialog();
//必须这样创建,不然窗口优先级不对
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL, new HashMap<>(), shareDialog);

Loading…
Cancel
Save