Browse Source

Merge branch 'feature/10.0' into release/10.0

# Conflicts:
#	designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java
feature/big-screen
vito 5 years ago
parent
commit
cfcd0ff50c
  1. 8
      .gitignore
  2. 82
      build.gradle
  3. 3
      designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java
  4. 18
      designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java
  5. 12
      designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java
  6. 12
      designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java
  7. 7
      designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java
  8. 234
      designer-base/src/main/java/com/fr/design/extra/QQLoginWebPane.java
  9. 15
      designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java
  10. 2
      designer-base/src/main/java/com/fr/design/gui/frpane/UIBubbleFloatPane.java
  11. 31
      designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java
  12. 17
      designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java
  13. 1
      designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java
  14. 13
      designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextArea.java
  15. 3
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  16. 20
      designer-base/src/main/java/com/fr/design/os/impl/MacOsAddListenerAction.java
  17. 68
      designer-base/src/main/java/com/fr/design/ui/Assistant.java
  18. 130
      designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java
  19. 147
      designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java
  20. 85
      designer-base/src/main/java/com/fr/design/ui/NxComplexInterceptRequestCallback.java
  21. 134
      designer-base/src/main/java/com/fr/design/ui/NxInterceptRequestCallback.java
  22. 230
      designer-base/src/main/java/com/fr/design/upm/UpmBridge.java
  23. 2
      designer-base/src/main/java/com/fr/design/upm/UpmFinder.java
  24. 15
      designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java
  25. 15
      designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java
  26. 200
      designer-base/src/main/java/com/fr/design/utils/AWTUtilities.java
  27. 3
      designer-base/src/main/java/com/fr/start/SplashWindow.java
  28. 41
      designer-base/src/test/java/com/fr/design/gui/icombocheckbox/UICheckListPopupTest.java
  29. 3
      designer-chart/build.gradle
  30. 3
      designer-form/build.gradle
  31. 4
      designer-realize/build.gradle
  32. 2
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/listener/ComponentHandler.java
  33. 29
      globalConfigHook.gradle
  34. BIN
      gradle/wrapper/gradle-wrapper.jar
  35. 6
      gradle/wrapper/gradle-wrapper.properties
  36. 172
      gradlew
  37. 84
      gradlew.bat
  38. 4
      pom.xml
  39. 12
      settings.gradle

8
.gitignore vendored

@ -3,6 +3,14 @@
.DS_Store .DS_Store
.classpath .classpath
.project .project
.gradle
target/ target/
*/build
designer-base/${web-inf-path}
designer-chart/${web-inf-path}
designer-form/${web-inf-path}
designer-realize/${web-inf-path}

82
build.gradle

@ -0,0 +1,82 @@
import org.gradle.plugins.ide.idea.model.IdeaLanguageLevel
plugins {
id 'java'
id 'java-library'
id 'com.fr.common' version '1.0-SNAPSHOT'
}
//
ext {
frVersion = ""
outputPath = "build"
ignoreTestFailureSetting = true
languageLevelSetting = 1.8
}
applyGlobalConfigPathIfExist()
if (versions.frVersion) {
frVersion = versions.frVersion
}
def frDevVersion = "DEV" + frVersion
dependencies {
api project(':designer-base')
api project(':designer-chart')
api project(':designer-form')
api project(':designer-realize')
}
allprojects {
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'idea'
group 'com.fr.design'
version frDevVersion
sourceCompatibility = languageLevelSetting
targetCompatibility = languageLevelSetting
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
repositories {
mavenLocal()
}
idea {
module {
inheritOutputDirs = false
outputDir = file(outputPath +"/classes")
testOutputDir = file(outputPath +"/test-classes")
languageLevel = new IdeaLanguageLevel(sourceCompatibility)
targetBytecodeVersion = targetCompatibility
}
}
dependencies {
implementation 'com.fr.third:jxbrowser:7.5'
implementation 'com.fr.third:jxbrowser-swing:7.5'
implementation 'com.fr.third:jxbrowser-mac:7.5'
implementation 'com.fr.third:jxbrowser-win64:7.5'
implementation 'com.fr.third.server:servlet-api:3.0'
implementation 'org.swingexplorer:swexpl:2.0.1'
implementation 'org.swingexplorer:swag:1.0'
implementation 'net.java.dev.jna:jna:5.4.0'
implementation 'org.apache.tomcat:tomcat-catalina:8.5.32'
implementation 'io.socket:socket.io-client:0.7.0'
implementation 'com.fr.third:fine-third:' + frVersion
implementation 'com.fr.core:fine-core:' + frVersion
implementation 'com.fr.activator:fine-activator:' + frVersion
implementation 'com.fr.datasource:fine-datasource:' + frVersion
implementation 'com.fr.decision:fine-decision:' + frVersion
implementation 'com.fr.schedule:fine-schedule:' + frVersion
implementation 'com.fr.report:fine-report-engine:' + frDevVersion
testImplementation 'org.easymock:easymock:3.5.1'
testImplementation 'org.powermock:powermock-module-junit4:1.7.1'
testImplementation 'org.powermock:powermock-api-easymock:1.7.1'
testImplementation 'junit:junit:4.12'
}
}

3
designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java

@ -4,5 +4,8 @@ package com.fr.design.bridge.exec;
* Created by ibm on 2017/6/21. * Created by ibm on 2017/6/21.
*/ */
public interface JSExecutor { public interface JSExecutor {
String CALLBACK_FUNCTION_NAME = "action";
void executor(String newValue); void executor(String newValue);
} }

18
designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java

@ -2,9 +2,8 @@ package com.fr.design.dcm;
import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.BasicPane;
import com.fr.design.ui.ModernUIPane; import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.chromium.JSValue; import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import java.awt.*; import java.awt.*;
@ -26,14 +25,13 @@ public class UniversalDatabasePane extends BasicPane {
setLayout(new BorderLayout()); setLayout(new BorderLayout());
modernUIPane = new ModernUIPane.Builder<>() modernUIPane = new ModernUIPane.Builder<>()
.withComponent(UniversalDatabaseComponent.KEY) .withComponent(UniversalDatabaseComponent.KEY)
.prepare(new ScriptContextAdapter() { .prepare(params -> {
@Override JsObject window = params.frame().executeJavaScript("window");
public void onScriptContextCreated(ScriptContextEvent event) { if (window != null) {
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); window.putProperty("DcmHelper", UniversalDcmBridge.getBridge());
window.asObject().setProperty("DcmHelper", UniversalDcmBridge.getBridge(event.getBrowser()));
} }
}) return InjectJsCallback.Response.proceed();
.build(); }).build();
add(modernUIPane, BorderLayout.CENTER); add(modernUIPane, BorderLayout.CENTER);
} }
} }

12
designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java

@ -2,8 +2,6 @@ package com.fr.design.dcm;
import com.fr.decision.webservice.bean.BaseBean; import com.fr.decision.webservice.bean.BaseBean;
import com.fr.design.bridge.exec.JSBridge; import com.fr.design.bridge.exec.JSBridge;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSObject;
/** /**
* @author richie * @author richie
@ -13,18 +11,18 @@ import com.teamdev.jxbrowser.chromium.JSObject;
*/ */
public class UniversalDcmBridge { public class UniversalDcmBridge {
public static UniversalDcmBridge getBridge(Browser browser) { public static UniversalDcmBridge getBridge() {
return new UniversalDcmBridge(browser); return new UniversalDcmBridge();
} }
private JSObject window;
private UniversalDcmBridge(Browser browser) { private UniversalDcmBridge() {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
} }
/** /**
* 获取所有的数据连接 * 获取所有的数据连接
*
* @return 数据连接集合 * @return 数据连接集合
*/ */
@JSBridge @JSBridge

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

@ -196,18 +196,6 @@ public class LoginWebBridge {
uiLabel.setBackground(LOGIN_BACKGROUND); uiLabel.setBackground(LOGIN_BACKGROUND);
} }
/**
* 弹出QQ授权页面
*/
public void showQQ() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
WebViewDlgHelper.createQQLoginDialog();
}
});
}
/** /**
* 关闭QQ授权窗口 * 关闭QQ授权窗口
*/ */

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

@ -533,13 +533,6 @@ public class PluginWebBridge {
threadPoolExecutor.submit(task); threadPoolExecutor.submit(task);
} }
/**
* 弹出QQ授权页面
*/
public void showQQ() {
LoginWebBridge.getHelper().showQQ();
}
/** /**
* 通过QQ登录后通知登录 * 通过QQ登录后通知登录
*/ */

234
designer-base/src/main/java/com/fr/design/extra/QQLoginWebPane.java

@ -1,234 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.control.LabelBuilder;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.HBoxBuilder;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.stage.Modality;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
import javafx.util.Callback;
import netscape.javascript.JSObject;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.awt.Toolkit;
/**
* Created by zhaohehe on 16/7/28.
*/
public class QQLoginWebPane extends JFXPanel {
private WebEngine webEngine;
private String url;
private static JSObject window;
private static int DEFAULT_PRIMARYSTAGE_WIDTH = 100;
private static int DEFAULT_PRIMARYSTAGE_HEIGHT = 100;
private static int DEFAULT_CONFIRM_WIDTH = 450;
private static int DEFAULT_CONFIRM_HEIGHT = 160;
private static int DEFAULT_OFFEST = 20;
class Delta {
double x, y;
}
public QQLoginWebPane(final String installHome) {
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
QQLoginWebPane.this.setScene(scene);
final WebView webView = new WebView();
webEngine = webView.getEngine();
url = "file:///" + installHome + "/scripts/qqLogin.html";
webEngine.load(url);
final Stage primaryStage = new Stage();
HBox layout = new HBox();
try {
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(new Scene(layout));
webView.getScene().getStylesheets().add(IOUtils.getResource("modal-dialog.css", getClass()).toExternalForm());
primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.setScene(new Scene(new Group(), DEFAULT_PRIMARYSTAGE_WIDTH, DEFAULT_PRIMARYSTAGE_HEIGHT));
primaryStage.setX(0);
primaryStage.setY(Screen.getPrimary().getBounds().getHeight() + DEFAULT_PRIMARYSTAGE_HEIGHT);
primaryStage.show();
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
webEngine.setConfirmHandler(new Callback<String, Boolean>() {
@Override
public Boolean call(String msg) {
Boolean confirmed = confirm(primaryStage, msg, webView);
return confirmed;
}
});
configWebEngine();
webView.setContextMenuEnabled(false);//屏蔽右键
root.setCenter(webView);
}
});
}
private void configWebEngine() {
webEngine.locationProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, final String oldValue, String newValue) {
disableLink(webEngine);
// webView好像默认以手机版显示网页,浏览器里过滤掉这个跳转
if (ComparatorUtils.equals(newValue, url) || ComparatorUtils.equals(newValue, CloudCenter.getInstance().acquireUrlByKind("bbs.mobile"))) {
return;
}
LoginWebBridge.getHelper().openUrlAtLocalWebBrowser(webEngine, newValue);
}
});
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
showAlert(event.getData());
}
});
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<Worker.State>() {
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
if (newState == Worker.State.SUCCEEDED) {
window = (JSObject) webEngine.executeScript("window");
window.setMember("QQLoginHelper", LoginWebBridge.getHelper());
}
}
}
);
}
private void showAlert(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(QQLoginWebPane.this, message);
}
});
}
private void disableLink(final WebEngine eng) {
try {
// webView端不跳转 虽然webView可以指定本地浏览器打开某个链接,但是当本地浏览器跳转到指定链接的同时,webView也做了跳转,
// 为了避免出现在一个600*400的资讯框里加载整个网页的情况,webView不跳转到新网页
Platform.runLater(new Runnable() {
@Override
public void run() {
eng.executeScript("location.reload()");
LoginWebBridge.getHelper().closeQQWindow();
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private Boolean confirm(final Stage parent, String msg, final WebView webView) {
final BooleanProperty confirmationResult = new SimpleBooleanProperty();
// initialize the confirmation dialog
final Stage dialog = new Stage(StageStyle.UTILITY);
dialog.setX(Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - DEFAULT_CONFIRM_WIDTH / 2.0D + DEFAULT_OFFEST);
dialog.setY(Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 + DEFAULT_OFFEST);
dialog.setHeight(DEFAULT_CONFIRM_HEIGHT);
dialog.setWidth(DEFAULT_CONFIRM_WIDTH);
dialog.setIconified(false);
dialog.initOwner(parent);
dialog.initModality(Modality.WINDOW_MODAL);
dialog.setScene(
new Scene(
HBoxBuilder.create().styleClass("modal-dialog").children(
LabelBuilder.create().text(msg).build(),
ButtonBuilder.create().text(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Switch_Account")).defaultButton(true).onAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
// take action and close the dialog.
confirmationResult.set(true);
webView.getEngine().reload();
dialog.close();
}
}).build(),
ButtonBuilder.create().text(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Engine_Cancel")).cancelButton(true).onAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
// abort action and close the dialog.
confirmationResult.set(false);
dialog.close();
}
}).build()
).build()
, Color.TRANSPARENT
)
);
configDrag(dialog);
// style and show the dialog.
dialog.getScene().getStylesheets().add(IOUtils.getResource("modal-dialog.css", getClass()).toExternalForm());
dialog.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
event.consume();
dialog.close();
}
});
dialog.showAndWait();
return confirmationResult.get();
}
private void configDrag(final Stage dialog) {
// allow the dialog to be dragged around.
final Node root = dialog.getScene().getRoot();
final Delta dragDelta = new Delta();
root.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = dialog.getX() - mouseEvent.getScreenX();
dragDelta.y = dialog.getY() - mouseEvent.getScreenY();
}
});
root.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
dialog.setX(mouseEvent.getScreenX() + dragDelta.x);
dialog.setY(mouseEvent.getScreenY() + dragDelta.y);
}
});
}
}

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

@ -183,21 +183,6 @@ public class WebViewDlgHelper {
} }
} }
public static void createQQLoginDialog() {
try {
Class<?> clazz = Class.forName("com.fr.design.extra.QQLoginWebPane");
Constructor constructor = clazz.getConstructor(String.class);
Component webPane = (Component) constructor.newInstance(new File(installHome).getAbsolutePath());
UIDialog qqLoginDialog = new QQLoginDialog(DesignerContext.getDesignerFrame(), webPane);
LoginWebBridge.getHelper().setQQDialog(qqLoginDialog);
qqLoginDialog.setVisible(true);
} catch (Throwable ignored) {
// ignored
}
}
private static void confirmDownLoadShopJS() { private static void confirmDownLoadShopJS() {
int rv = FineJOptionPane.showConfirmDialog( int rv = FineJOptionPane.showConfirmDialog(
null, null,

2
designer-base/src/main/java/com/fr/design/gui/frpane/UIBubbleFloatPane.java

@ -2,9 +2,9 @@ package com.fr.design.gui.frpane;
import com.fr.design.beans.BasicBeanPane; import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.UIDialog; import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.AWTUtilities;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.Constants; import com.fr.stable.Constants;
import com.sun.awt.AWTUtilities;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;

31
designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java

@ -36,14 +36,20 @@ public class UICheckListPopup extends UIPopupMenu {
private UIScrollPane jScrollPane; private UIScrollPane jScrollPane;
private Color mouseEnteredColor = UIConstants.CHECKBOX_HOVER_SELECTED; private Color mouseEnteredColor = UIConstants.CHECKBOX_HOVER_SELECTED;
private int maxDisplayNumber = 8; private int maxDisplayNumber = 8;
private boolean supportSelectAll = true;
public static final String COMMIT_EVENT = "commit"; public static final String COMMIT_EVENT = "commit";
public static final String SELECT_ALL = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Choose_All"); private static final String SELECT_ALL = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Choose_All");
private static final int CHECKBOX_HEIGHT = 25; private static final int CHECKBOX_HEIGHT = 25;
public UICheckListPopup(Object[] value) { public UICheckListPopup(Object[] values) {
this(values, true);
}
public UICheckListPopup(Object[] value, boolean supportSelectAll) {
super(); super();
values = value; values = value;
this.supportSelectAll = supportSelectAll;
initComponent(); initComponent();
} }
@ -78,7 +84,9 @@ public class UICheckListPopup extends UIPopupMenu {
checkBoxList.clear(); checkBoxList.clear();
//全选加在第一个位置 //全选加在第一个位置
addOneCheckValue(SELECT_ALL); if (supportSelectAll) {
addOneCheckValue(SELECT_ALL);
}
for (Object checkValue : values) { for (Object checkValue : values) {
addOneCheckValue(checkValue); addOneCheckValue(checkValue);
} }
@ -151,7 +159,7 @@ public class UICheckListPopup extends UIPopupMenu {
private void addSelectListener() { private void addSelectListener() {
for (int i = 0; i < checkBoxList.size(); i++) { for (int i = 0; i < checkBoxList.size(); i++) {
JCheckBox checkBox = checkBoxList.get(i); JCheckBox checkBox = checkBoxList.get(i);
if (i == 0) { if (supportSelectAll && i == 0) {
checkBox.addItemListener(new ItemListener() { checkBox.addItemListener(new ItemListener() {
@Override @Override
public void itemStateChanged(ItemEvent e) { public void itemStateChanged(ItemEvent e) {
@ -189,7 +197,8 @@ public class UICheckListPopup extends UIPopupMenu {
List<Object> allValue = Arrays.asList(values); List<Object> allValue = Arrays.asList(values);
for (Object value : selectedValues.keySet()) { for (Object value : selectedValues.keySet()) {
int index = allValue.indexOf(value); int index = allValue.indexOf(value);
checkBoxList.get(index + 1).setSelected(selectedValues.get(value)); index = supportSelectAll ? index + 1 : index;
checkBoxList.get(index).setSelected(selectedValues.get(value));
} }
} }
@ -201,15 +210,19 @@ public class UICheckListPopup extends UIPopupMenu {
public Object[] getSelectedValues() { public Object[] getSelectedValues() {
List<Object> selectedValues = new ArrayList<Object>(); List<Object> selectedValues = new ArrayList<Object>();
int selectCount = 0; int selectCount = 0;
int startIndex = supportSelectAll ? 1 : 0;
for (int i = 1; i < checkBoxList.size(); i++) { for (int i = startIndex; i < checkBoxList.size(); i++) {
if (checkBoxList.get(i).isSelected()) { if (checkBoxList.get(i).isSelected()) {
selectedValues.add(values[i - 1]); int valueIndex = supportSelectAll ? i - 1 : i;
selectedValues.add(values[valueIndex]);
selectCount++; selectCount++;
} }
} }
//全选半选切换 //全选半选切换
switchSelectIcon(selectCount); if (supportSelectAll) {
switchSelectIcon(selectCount);
}
return selectedValues.toArray(new Object[selectedValues.size()]); return selectedValues.toArray(new Object[selectedValues.size()]);
} }

17
designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java

@ -59,8 +59,18 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
private String multiComboName = StringUtils.EMPTY; private String multiComboName = StringUtils.EMPTY;
private boolean showOmitText = true; private boolean showOmitText = true;
private boolean supportSelectAll = true;
public UIComboCheckBox(Object[] value) { public UIComboCheckBox(Object[] value) {
this(value, DEFAULT_VALUE_SPERATOR); this(value, DEFAULT_VALUE_SPERATOR, true);
}
public UIComboCheckBox(Object[] value, boolean supportSelectAll) {
this(value, DEFAULT_VALUE_SPERATOR, supportSelectAll);
}
public UIComboCheckBox(Object[] values, String valueSperator) {
this(values, valueSperator, true);
} }
/** /**
@ -69,8 +79,9 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
* @param value * @param value
* @param valueSperator * @param valueSperator
*/ */
public UIComboCheckBox(Object[] value, String valueSperator) { public UIComboCheckBox(Object[] value, String valueSperator, boolean supportSelectAll) {
values = value; values = value;
this.supportSelectAll = supportSelectAll;
this.valueSperator = valueSperator; this.valueSperator = valueSperator;
initComponent(); initComponent();
} }
@ -102,7 +113,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
private void initComponent() { private void initComponent() {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
this.popup = new UICheckListPopup(values); this.popup = new UICheckListPopup(values, supportSelectAll);
this.popup.addActionListener(new PopupAction()); this.popup.addActionListener(new PopupAction());
this.editor = createEditor(); this.editor = createEditor();
this.arrowButton = createArrowButton(); this.arrowButton = createArrowButton();

1
designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java

@ -1,5 +1,6 @@
package com.fr.design.gui.ifilechooser; package com.fr.design.gui.ifilechooser;
import com.fr.design.gui.ifilechooser.AbstractFileChooser;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.stable.os.OperatingSystem; import com.fr.stable.os.OperatingSystem;

13
designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextArea.java

@ -9,16 +9,7 @@
*/ */
package com.fr.design.gui.syntax.ui.rsyntaxtextarea; package com.fr.design.gui.syntax.ui.rsyntaxtextarea;
import java.awt.Color; import java.awt.*;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.Clipboard;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@ -604,7 +595,7 @@ private boolean fractionalFontMetricsEnabled;
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm!=null) { if (sm!=null) {
try { try {
sm.checkSystemClipboardAccess(); sm.checkPermission(new AWTPermission("accessClipboard"));
} catch (SecurityException se) { } catch (SecurityException se) {
UIManager.getLookAndFeel().provideErrorFeedback(null); UIManager.getLookAndFeel().provideErrorFeedback(null);
return; return;

3
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java

@ -509,7 +509,8 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
if (OperatingSystem.isMacos()) { if (OperatingSystem.isMacos()) {
Class clazz = Class.forName("com.apple.eawt.Application"); Class clazz = Class.forName("com.apple.eawt.Application");
BufferedImage icon = image.isEmpty() ? IOUtils.readImage("/com/fr/base/images/oem/logo.png") : image.get(image.size() - 1); BufferedImage icon = image.isEmpty() ? IOUtils.readImage("/com/fr/base/images/oem/logo.png") : image.get(image.size() - 1);
Reflect.on(Reflect.on(clazz).call("getApplication").get()).call("setDockIconImage", icon); Object application = Reflect.on(clazz).call("getApplication").get();
Reflect.on(application).call("setDockIconImage", icon);
} else { } else {
this.setIconImages(image); this.setIconImages(image);
} }

20
designer-base/src/main/java/com/fr/design/os/impl/MacOsAddListenerAction.java

@ -9,11 +9,16 @@ import com.fr.invoke.Reflect;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.os.support.OSBasedAction; import com.fr.stable.os.support.OSBasedAction;
import java.awt.*;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
/** /**
* com.apple.eawt.Application属于jdk1.8及以下mac jdk特有的api
* 在jdk9中被移除由Desktop.getDesktop().setQuitHandler等jdk9.0引入的新api替代
* 参见 https://stackoverflow.com/questions/38381824/how-can-i-use-apple-com-apple-eawt-functionality-on-java-8
*
* @author hades * @author hades
* @version 10.0 * @version 10.0
* Created by hades on 2020/3/13 * Created by hades on 2020/3/13
@ -28,10 +33,21 @@ public class MacOsAddListenerAction implements OSBasedAction {
Object quitInstance = getProxy(quitHandler, "handleQuitRequestWith", new QuitAction()); Object quitInstance = getProxy(quitHandler, "handleQuitRequestWith", new QuitAction());
Class aboutHandler = Class.forName("com.apple.eawt.AboutHandler"); Class aboutHandler = Class.forName("com.apple.eawt.AboutHandler");
Object aboutInstance = getProxy(aboutHandler, "handleAbout", new AboutAction()); Object aboutInstance = getProxy(aboutHandler, "handleAbout", new AboutAction());
Reflect.on(Reflect.on(app).call("getApplication").get()).call("setQuitHandler", quitInstance) Object application = Reflect.on(app).call("getApplication").get();
Reflect.on(application).call("setQuitHandler", quitInstance)
.call("setAboutHandler", aboutInstance); .call("setAboutHandler", aboutInstance);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); // 上面的不能移除,同时要保证再jdk1.8下面能运行
// 抛出异常时 说明使用>=jdk9运行行设计器,但由于编译使用1.8构建,使用反射运行
try {
Class quitHandler = Class.forName("java.awt.desktop.QuitHandler");
Object quitInstance = getProxy(quitHandler, "handleQuitRequestWith", new QuitAction());
Class aboutHandler = Class.forName("java.awt.desktop.AboutHandler");
Object aboutInstance = getProxy(aboutHandler, "handleAbout", new AboutAction());
Reflect.on(Desktop.getDesktop()).call("setQuitHandler", quitInstance).call("setAboutHandler", aboutInstance);
} catch (ClassNotFoundException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
} }
} }

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

@ -1,68 +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.ProtocolService;
import com.teamdev.jxbrowser.chromium.URLResponse;
import javax.activation.MimetypesFileTypeMap;
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.nio.file.Paths;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-07
*/
public class Assistant {
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";
}
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);
}
}

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

@ -1,130 +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);
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;
}
}

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

@ -7,21 +7,18 @@ import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.web.struct.AssembleComponent; import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.chromium.Browser; import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.chromium.BrowserPreferences; import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.JSValue; import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.chromium.events.FinishLoadingEvent; import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.chromium.events.LoadAdapter; import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.chromium.events.LoadListener; import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.net.Network;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; import com.teamdev.jxbrowser.view.swing.BrowserView;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map; import java.util.Map;
/** /**
@ -42,9 +39,8 @@ public class ModernUIPane<T> extends BasicPane {
} }
private void initialize() { private void initialize() {
setLayout(new BorderLayout());
if (browser == null) { if (browser == null) {
setLayout(new BorderLayout());
BrowserPreferences.setChromiumSwitches("--disable-google-traffic");
if (DesignerEnvManager.getEnvManager().isOpenDebug()) { if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
UIToolbar toolbar = new UIToolbar(); UIToolbar toolbar = new UIToolbar();
add(toolbar, BorderLayout.NORTH); add(toolbar, BorderLayout.NORTH);
@ -55,75 +51,67 @@ public class ModernUIPane<T> extends BasicPane {
UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window")); UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window"));
toolbar.add(closeButton); toolbar.add(closeButton);
openDebugButton.addActionListener(new ActionListener() { openDebugButton.addActionListener(e -> showDebuggerDialog());
@Override
public void actionPerformed(ActionEvent e) {
showDebuggerDialog();
}
});
reloadButton.addActionListener(new ActionListener() { reloadButton.addActionListener(e -> browser.navigation().reloadIgnoringCache());
@Override
public void actionPerformed(ActionEvent e) {
browser.reloadIgnoringCache();
}
});
closeButton.addActionListener(new ActionListener() { closeButton.addActionListener(e -> SwingUtilities.getWindowAncestor(ModernUIPane.this).setVisible(false));
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.getWindowAncestor(ModernUIPane.this).setVisible(false);
}
});
BrowserPreferences.setChromiumSwitches("--remote-debugging-port=9222");
initializeBrowser(); initializeBrowser();
add(new BrowserView(browser), BorderLayout.CENTER); add(BrowserView.newInstance(browser), BorderLayout.CENTER);
} else { } else {
initializeBrowser(); initializeBrowser();
add(new BrowserView(browser), BorderLayout.CENTER); add(BrowserView.newInstance(browser), BorderLayout.CENTER);
} }
} }
} }
private void showDebuggerDialog() { private void showDebuggerDialog() {
JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this)); JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this));
Browser debugger = new Browser(); Engine engine = Engine.newInstance(
BrowserView debuggerView = new BrowserView(debugger); EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED)
.addSwitch("--disable-google-traffic")
.remoteDebuggingPort(9222).build());
Browser debugger = engine.newBrowser();
BrowserView debuggerView = BrowserView.newInstance(debugger);
dialog.add(debuggerView, BorderLayout.CENTER); dialog.add(debuggerView, BorderLayout.CENTER);
dialog.setSize(new Dimension(800, 400)); dialog.setSize(new Dimension(800, 400));
GUICoreUtils.centerWindow(dialog); GUICoreUtils.centerWindow(dialog);
dialog.setVisible(true); dialog.setVisible(true);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
debugger.loadURL(browser.getRemoteDebuggingURL()); browser.devTools().remoteDebuggingUrl().ifPresent(url -> {
debugger.navigation().loadUrl(url);
});
} }
private void initializeBrowser() { private void initializeBrowser() {
browser = new Browser(); Engine engine = Engine.newInstance(EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").build());
browser = engine.newBrowser();
// 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的 // 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的
browser.addScriptContextListener(new ScriptContextAdapter() { browser.set(InjectJsCallback.class, params -> {
@Override params.frame().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace));
public void onScriptContextCreated(ScriptContextEvent event) { return InjectJsCallback.Response.proceed();
event.getBrowser().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace));
}
}); });
} }
/** /**
* 转向一个新的地址相当于重新加载 * 转向一个新的地址相当于重新加载
*
* @param url 新的地址 * @param url 新的地址
*/ */
public void redirect(String url) { public void redirect(String url) {
browser.loadURL(url); browser.navigation().loadUrl(url);
} }
/** /**
* 转向一个新的地址相当于重新加载 * 转向一个新的地址相当于重新加载
*
* @param url 新的地址 * @param url 新的地址
* @param map 初始化参数 * @param map 初始化参数
*/ */
public void redirect(String url, Map<String, String> map) { public void redirect(String url, Map<String, String> map) {
Assistant.setEmbProtocolHandler(browser, new EmbProtocolHandler(map)); Network network = browser.engine().network();
browser.loadURL(url); network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map));
browser.navigation().loadUrl(url);
} }
@Override @Override
@ -133,19 +121,18 @@ public class ModernUIPane<T> extends BasicPane {
public void populate(final T t) { public void populate(final T t) {
browser.addScriptContextListener(new ScriptContextAdapter() { browser.set(InjectJsCallback.class, params -> {
@Override JsObject ns = params.frame().executeJavaScript("window." + namespace);
public void onScriptContextCreated(ScriptContextEvent event) { if (ns != null) {
JSValue ns = event.getBrowser().executeJavaScriptAndReturnValue("window." + namespace); ns.putProperty(variable, t);
ns.asObject().setProperty(variable, t);
} }
return InjectJsCallback.Response.proceed();
}); });
} }
public T update() { public T update() {
JSValue jsValue = browser.executeJavaScriptAndReturnValue("window." + namespace + "." + expression); if (browser.mainFrame().isPresent()) {
if (jsValue.isObject()) { return browser.mainFrame().get().executeJavaScript("window." + namespace + "." + expression);
return (T)jsValue.asJavaObject();
} }
return null; return null;
} }
@ -154,79 +141,89 @@ public class ModernUIPane<T> extends BasicPane {
private ModernUIPane<T> pane = new ModernUIPane<>(); private ModernUIPane<T> pane = new ModernUIPane<>();
public Builder<T> prepare(ScriptContextListener contextListener) { public Builder<T> prepare(InjectJsCallback callback) {
pane.browser.addScriptContextListener(contextListener); pane.browser.set(InjectJsCallback.class, callback);
return this;
}
public Builder<T> prepare(LoadListener loadListener) {
pane.browser.addLoadListener(loadListener);
return this; return this;
} }
/** /**
* 加载jar包中的资源 * 加载jar包中的资源
*
* @param path 资源路径 * @param path 资源路径
*/ */
public Builder<T> withEMB(final String path) { public Builder<T> withEMB(final String path) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); Network network = pane.browser.engine().network();
pane.browser.loadURL("emb:" + path); network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network));
pane.browser.navigation().loadUrl("emb:" + path);
return this; return this;
} }
/** /**
* 加载url指向的资源 * 加载url指向的资源
*
* @param url 文件的地址 * @param url 文件的地址
*/ */
public Builder<T> withURL(final String url) { public Builder<T> withURL(final String url) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); Network network = pane.browser.engine().network();
pane.browser.loadURL(url); network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network));
pane.browser.navigation().loadUrl(url);
return this; return this;
} }
/** /**
* 加载url指向的资源 * 加载url指向的资源
*
* @param url 文件的地址 * @param url 文件的地址
*/ */
public Builder<T> withURL(final String url, Map<String, String> map) { public Builder<T> withURL(final String url, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(map)); Network network = pane.browser.engine().network();
pane.browser.loadURL(url); network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map));
pane.browser.navigation().loadUrl(url);
return this; return this;
} }
/** /**
* 加载Atom组件 * 加载Atom组件
*
* @param component Atom组件 * @param component Atom组件
*/ */
public Builder<T> withComponent(AssembleComponent component) { public Builder<T> withComponent(AssembleComponent component) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component)); Network network = pane.browser.engine().network();
pane.browser.loadURL("emb:dynamic"); network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component));
pane.browser.navigation().loadUrl("emb:dynamic");
return this; return this;
} }
/** /**
* 加载Atom组件 * 加载Atom组件
*
* @param component Atom组件 * @param component Atom组件
*/ */
public Builder<T> withComponent(AssembleComponent component, Map<String, String> map) { public Builder<T> withComponent(AssembleComponent component, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component, map)); Network network = pane.browser.engine().network();
pane.browser.loadURL("emb:dynamic"); network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component, map));
pane.browser.navigation().loadUrl("emb:dynamic");
return this; return this;
} }
/** /**
* 加载html文本内容 * 加载html文本内容
*
* @param html 要加载html文本内容 * @param html 要加载html文本内容
*/ */
public Builder<T> withHTML(String html) { public Builder<T> withHTML(String html) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); Network network = pane.browser.engine().network();
pane.browser.loadHTML(html); network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network));
pane.browser.mainFrame().ifPresent(frame -> {
frame.loadHtml(html);
});
return this; return this;
} }
/** /**
* 设置该前端页面做数据交换所使用的对象 * 设置该前端页面做数据交换所使用的对象
*
* @param namespace 对象名 * @param namespace 对象名
*/ */
public Builder<T> namespace(String namespace) { public Builder<T> namespace(String namespace) {
@ -236,6 +233,7 @@ public class ModernUIPane<T> extends BasicPane {
/** /**
* java端往js端传数据时使用的变量名字 * java端往js端传数据时使用的变量名字
*
* @param name 变量的名字 * @param name 变量的名字
*/ */
public Builder<T> variable(String name) { public Builder<T> variable(String name) {
@ -245,6 +243,7 @@ public class ModernUIPane<T> extends BasicPane {
/** /**
* js端往java端传数据时执行的函数表达式 * js端往java端传数据时执行的函数表达式
*
* @param expression 函数表达式 * @param expression 函数表达式
*/ */
public Builder<T> expression(String expression) { public Builder<T> expression(String expression) {

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

@ -0,0 +1,85 @@
package com.fr.design.ui;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
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.net.Network;
import com.teamdev.jxbrowser.net.UrlRequest;
import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @author richie
* @version 10.0
* Created by richie on 2020/3/25
*/
public class NxComplexInterceptRequestCallback extends NxInterceptRequestCallback {
private AssembleComponent component;
public NxComplexInterceptRequestCallback(Network network, AssembleComponent component) {
super(network);
this.component = component;
}
public NxComplexInterceptRequestCallback(Network network, AssembleComponent component, Map<String, String> map) {
super(network, map);
this.component = component;
}
@Override
protected Response next(UrlRequest urlRequest, String path) {
if (path.startsWith("emb:dynamic")) {
String text = htmlText(map);
return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, "text/html", text.getBytes(StandardCharsets.UTF_8)));
} else {
int index = path.indexOf("=");
if (index > 0) {
path = path.substring(index + 1);
} else {
path = path.substring(4);
}
InputStream inputStream = IOUtils.readResource(path);
return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, getMimeType(path), IOUtils.inputStream2Bytes(inputStream)));
}
}
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;
}
}

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

@ -0,0 +1,134 @@
package com.fr.design.ui;
import com.fr.base.TemplateUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.codec.net.URLCodec;
import com.teamdev.jxbrowser.net.HttpHeader;
import com.teamdev.jxbrowser.net.HttpStatus;
import com.teamdev.jxbrowser.net.Network;
import com.teamdev.jxbrowser.net.UrlRequest;
import com.teamdev.jxbrowser.net.UrlRequestJob;
import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
/**
* @author richie
* @version 10.0
* Created by richie on 2020/3/25
*/
public class NxInterceptRequestCallback implements InterceptRequestCallback {
Network network;
Map<String, String> map;
public NxInterceptRequestCallback(Network network) {
this.network = network;
}
public NxInterceptRequestCallback(Network network, Map<String, String> map) {
this.network = network;
this.map = map;
}
@Override
public Response on(Params params) {
UrlRequest urlRequest = params.urlRequest();
String path = urlRequest.url();
if (path.startsWith("file:")) {
Optional<UrlRequestJob> optional = generateFileProtocolUrlRequestJob(urlRequest, path);
if (optional.isPresent()) {
return InterceptRequestCallback.Response.intercept(optional.get());
}
} else {
return next(urlRequest, path);
}
return Response.proceed();
}
Response next(UrlRequest urlRequest, String path) {
return Response.proceed();
}
private Optional<UrlRequestJob> generateFileProtocolUrlRequestJob(UrlRequest urlRequest, String path) {
try {
String url = new URLCodec().decode(path);
String filePath = TemplateUtils.renderParameter4Tpl(url, map);
File file = new File(URI.create(filePath).getPath());
InputStream inputStream = IOUtils.readResource(file.getAbsolutePath());
String mimeType = getMimeType(path);
byte[] bytes;
if (isPlainText(mimeType)) {
String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8);
text = TemplateUtils.renderParameter4Tpl(text, map);
bytes = text.getBytes(StandardCharsets.UTF_8);
} else {
bytes = IOUtils.inputStream2Bytes(inputStream);
}
return Optional.of(generateBasicUrlRequestJob(urlRequest, mimeType, bytes));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return Optional.empty();
}
private boolean isPlainText(String mimeType) {
return ArrayUtils.contains(new String[]{"text/html", "text/javascript", "text/css"}, mimeType);
}
UrlRequestJob generateBasicUrlRequestJob(UrlRequest urlRequest, String mimeType, byte[] bytes) {
UrlRequestJob.Options options = UrlRequestJob.Options
.newBuilder(urlRequest.id(), HttpStatus.OK)
.addHttpHeader(HttpHeader.of("Content-Type", mimeType))
.build();
UrlRequestJob urlRequestJob = network.newUrlRequestJob(options);
urlRequestJob.write(bytes);
urlRequestJob.complete();
return urlRequestJob;
}
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";
}
if (path.endsWith(".png")) {
return "image/png";
}
if (path.endsWith(".jpeg")) {
return "image/jpeg";
}
if (path.endsWith(".gif")) {
return "image/gif";
}
Path file = new File(path).toPath();
try {
return Files.probeContentType(file);
} catch (IOException e) {
return "text/html";
}
}
}

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

@ -6,6 +6,7 @@ import com.fr.config.ServerPreferenceConfig;
import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader; import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader;
import com.fr.design.bridge.exec.JSBridge; import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.bridge.exec.JSCallback; import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.bridge.exec.JSExecutor;
import com.fr.design.extra.PluginOperateUtils; import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.extra.PluginUtils; import com.fr.design.extra.PluginUtils;
import com.fr.design.extra.exe.GetInstalledPluginsExecutor; import com.fr.design.extra.exe.GetInstalledPluginsExecutor;
@ -28,10 +29,8 @@ import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker; import com.fr.plugin.context.PluginMarker;
import com.fr.stable.ArrayUtils; import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.Browser; import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.chromium.JSArray; import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import javax.swing.*; import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
@ -52,42 +51,45 @@ import java.util.concurrent.RunnableFuture;
*/ */
public class UpmBridge { public class UpmBridge {
public static UpmBridge getBridge(Browser browser) { public static UpmBridge getBridge() {
return new UpmBridge(browser); return new UpmBridge();
} }
private JSObject window;
private UpmBridge(Browser browser) { private UpmBridge() {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
} }
/** /**
* 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新 * 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新
*
* @param callback 安装完成后的回调函数 * @param callback 安装完成后的回调函数
*/ */
@JSBridge @JSBridge
public void update(final JSFunction callback) { @JsAccessible
callback.invoke(window, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); public void update(final JsObject callback) {
callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start"));
try { try {
UpmResourceLoader.INSTANCE.download(); UpmResourceLoader.INSTANCE.download();
UpmResourceLoader.INSTANCE.install(); UpmResourceLoader.INSTANCE.install();
callback.invoke(window, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success"));
EventDispatcher.fire(DownloadEvent.UPDATE, "success"); EventDispatcher.fire(DownloadEvent.UPDATE, "success");
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
callback.invoke(window, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error"));
} }
} }
/** /**
* 下载并安装插件管理中心的资源文件 * 下载并安装插件管理中心的资源文件
*
* @param callback 安装完成后的回调函数 * @param callback 安装完成后的回调函数
*/ */
@JSBridge @JSBridge
public void startDownload(final JSFunction callback) { @JsAccessible
callback.invoke(window, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); public void startDownload(final JsObject callback) {
new SwingWorker<Void, Void>(){ callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start"));
new SwingWorker<Void, Void>() {
@Override @Override
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
UpmResourceLoader.INSTANCE.download(); UpmResourceLoader.INSTANCE.download();
@ -99,10 +101,10 @@ public class UpmBridge {
protected void done() { protected void done() {
try { try {
get(); get();
callback.invoke(window, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success"));
EventDispatcher.fire(DownloadEvent.SUCCESS, "success"); EventDispatcher.fire(DownloadEvent.SUCCESS, "success");
} catch (Exception e) { } catch (Exception e) {
callback.invoke(window, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error"));
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
EventDispatcher.fire(DownloadEvent.ERROR, "error"); EventDispatcher.fire(DownloadEvent.ERROR, "error");
} }
@ -112,37 +114,44 @@ public class UpmBridge {
/** /**
* 获取upm的版本信息 * 获取upm的版本信息
*
* @return 版本信息 * @return 版本信息
*/ */
@JSBridge @JSBridge
@JsAccessible
public String getVersion() { public String getVersion() {
return ServerPreferenceConfig.getInstance().getOptimizedUPMVersion(); return ServerPreferenceConfig.getInstance().getOptimizedUPMVersion();
} }
@JSBridge @JSBridge
@JsAccessible
public String i18nText(String key) { public String i18nText(String key) {
return Toolkit.i18nText(key); return Toolkit.i18nText(key);
} }
@JSBridge @JSBridge
@JsAccessible
public void closeWindow() { public void closeWindow() {
UpmFinder.closeWindow(); UpmFinder.closeWindow();
} }
@JSBridge @JSBridge
@JsAccessible
public boolean isDesigner() { public boolean isDesigner() {
return true; return true;
} }
@JSBridge @JSBridge
public void getPackInfo(final JSFunction callback) { @JsAccessible
callback.invoke(window, StringUtils.EMPTY); public void getPackInfo(final JsObject callback) {
callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, StringUtils.EMPTY);
} }
@JSBridge @JSBridge
public void getPluginPrefix(final JSFunction callback) { @JsAccessible
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginPrefixExecutor()); public void getPluginPrefix(final JsObject callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetPluginPrefixExecutor());
task.execute(); task.execute();
} }
@ -152,8 +161,9 @@ public class UpmBridge {
* @param callback 回调函数 * @param callback 回调函数
*/ */
@JSBridge @JSBridge
public void getPluginCategories(final JSFunction callback) { @JsAccessible
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginCategoriesExecutor()); public void getPluginCategories(final JsObject callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetPluginCategoriesExecutor());
task.execute(); task.execute();
} }
@ -164,8 +174,9 @@ public class UpmBridge {
* @param callback 回调函数 * @param callback 回调函数
*/ */
@JSBridge @JSBridge
public void getPluginFromStoreNew(String info, final JSFunction callback) { @JsAccessible
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginFromStoreExecutor(new JSONObject(info))); public void getPluginFromStoreNew(String info, final JsObject callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetPluginFromStoreExecutor(new JSONObject(info)));
task.execute(); task.execute();
} }
@ -173,8 +184,9 @@ public class UpmBridge {
* 已安装插件检查更新 * 已安装插件检查更新
*/ */
@JSBridge @JSBridge
public void readUpdateOnline(final JSFunction callback) { @JsAccessible
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new ReadUpdateOnlineExecutor()); public void readUpdateOnline(final JsObject callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new ReadUpdateOnlineExecutor());
task.execute(); task.execute();
} }
@ -182,8 +194,9 @@ public class UpmBridge {
* 获取已经安装的插件的数组 * 获取已经安装的插件的数组
*/ */
@JSBridge @JSBridge
public void getInstalledPlugins(final JSFunction callback) { @JsAccessible
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetInstalledPluginsExecutor()); public void getInstalledPlugins(final JsObject callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetInstalledPluginsExecutor());
task.execute(); task.execute();
} }
@ -193,29 +206,36 @@ public class UpmBridge {
* @param pluginIDs 插件集合 * @param pluginIDs 插件集合
*/ */
@JSBridge @JSBridge
public void updatePluginOnline(Object pluginIDs, final JSFunction callback) { @JsAccessible
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); public void updatePluginOnline(JsObject pluginIDs, final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
List<PluginMarker> pluginMarkerList = new ArrayList<>(); List<PluginMarker> pluginMarkerList = new ArrayList<>();
if (pluginIDs instanceof String) { for (String key : pluginIDs.propertyNames()) {
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginIDs.toString())); pluginIDs.property(key).ifPresent(v -> {
} else if (pluginIDs instanceof JSArray) { pluginMarkerList.add(PluginUtils.createPluginMarker(GeneralUtils.objectToString(v)));
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); PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
} }
@JSBridge
@JsAccessible
public void updatePluginOnline(String pluginID, final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
List<PluginMarker> pluginMarkerList = new ArrayList<>();
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginID));
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
/** /**
* 搜索在线插件 * 搜索在线插件
* *
* @param keyword 关键字 * @param keyword 关键字
*/ */
@JSBridge @JSBridge
public void searchPlugin(String keyword, final JSFunction callback) { @JsAccessible
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new SearchOnlineExecutor(keyword)); public void searchPlugin(String keyword, final JsObject callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new SearchOnlineExecutor(keyword));
worker.execute(); worker.execute();
} }
@ -225,8 +245,9 @@ public class UpmBridge {
* @param filePath 插件包的路径 * @param filePath 插件包的路径
*/ */
@JSBridge @JSBridge
public void installPluginFromDisk(final String filePath, final JSFunction callback) { @JsAccessible
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); public void installPluginFromDisk(final String filePath, final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
File file = new File(filePath); File file = new File(filePath);
PluginOperateUtils.installPluginFromDisk(file, jsCallback); PluginOperateUtils.installPluginFromDisk(file, jsCallback);
} }
@ -237,8 +258,9 @@ public class UpmBridge {
* @param pluginInfo 插件信息 * @param pluginInfo 插件信息
*/ */
@JSBridge @JSBridge
public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSFunction callback) { @JsAccessible
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback); PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
} }
@ -249,8 +271,9 @@ public class UpmBridge {
* @param callback 回调函数 * @param callback 回调函数
*/ */
@JSBridge @JSBridge
public void installPluginOnline(final String pluginInfo, final JSFunction callback) { @JsAccessible
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); public void installPluginOnline(final String pluginInfo, final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo); PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback); PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback);
} }
@ -260,8 +283,10 @@ public class UpmBridge {
* *
* @param filePath 插件包的路径 * @param filePath 插件包的路径
*/ */
public void updatePluginFromDisk(String filePath, final JSFunction callback) { @JSBridge
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); @JsAccessible
public void updatePluginFromDisk(String filePath, final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
File file = new File(filePath); File file = new File(filePath);
PluginOperateUtils.updatePluginFromDisk(file, jsCallback); PluginOperateUtils.updatePluginFromDisk(file, jsCallback);
} }
@ -272,8 +297,9 @@ public class UpmBridge {
* @param pluginID 插件ID * @param pluginID 插件ID
*/ */
@JSBridge @JSBridge
public void setPluginActive(String pluginID, final JSFunction callback) { @JsAccessible
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); public void setPluginActive(String pluginID, final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
PluginOperateUtils.setPluginActive(pluginID, jsCallback); PluginOperateUtils.setPluginActive(pluginID, jsCallback);
} }
@ -283,6 +309,7 @@ public class UpmBridge {
* @return 选择的文件的路径 * @return 选择的文件的路径
*/ */
@JSBridge @JSBridge
@JsAccessible
public String showFileChooser() { public String showFileChooser() {
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY); return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
} }
@ -296,6 +323,7 @@ public class UpmBridge {
* 这里换用JFileChooser会卡死,不知道为什么 * 这里换用JFileChooser会卡死,不知道为什么
*/ */
@JSBridge @JSBridge
@JsAccessible
public String showFileChooserWithFilter(final String des, final String filter) { public String showFileChooserWithFilter(final String des, final String filter) {
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() { RunnableFuture<String> future = new FutureTask<>(new Callable<String>() {
@Override @Override
@ -318,7 +346,7 @@ public class UpmBridge {
try { try {
return future.get(); return future.get();
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
} }
return null; return null;
} }
@ -331,31 +359,60 @@ public class UpmBridge {
* @return 选择的文件的路径 * @return 选择的文件的路径
*/ */
@JSBridge @JSBridge
public String showFileChooserWithFilters(final String des, final Object args) { @JsAccessible
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() { public String showFileChooserWithFilters(final String des, final String args) {
@Override RunnableFuture<String> future = new FutureTask<>(() -> {
public String call() { JFileChooser fileChooser = new JFileChooser();
JFileChooser fileChooser = new JFileChooser(); List<String> filterList = new ArrayList<>();
List<String> filterList = new ArrayList<>(); filterList.add(args);
if (args instanceof String) { String[] filters = filterList.toArray(new String[0]);
filterList.add(GeneralUtils.objectToString(args)); if (ArrayUtils.isNotEmpty(filters)) {
} else if (args instanceof JSArray) { FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters));
JSArray array = (JSArray)args; fileChooser.setFileFilter(filter);
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;
} }
int result = fileChooser.showOpenDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile().getAbsolutePath();
}
return null;
});
SwingUtilities.invokeLater(future);
try {
return future.get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
@JSBridge
@JsAccessible
public String showFileChooserWithFilters(final String des, final JsObject args) {
RunnableFuture<String> future = new FutureTask<>(() -> {
JFileChooser fileChooser = new JFileChooser();
List<String> filterList = new ArrayList<>();
for (String key : args.propertyNames()) {
args.property(key).ifPresent(v -> {
filterList.add(GeneralUtils.objectToString(v));
});
}
String[] filters = filterList.toArray(new String[0]);
if (ArrayUtils.isNotEmpty(filters)) {
FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters));
fileChooser.setFileFilter(filter);
}
int result = fileChooser.showOpenDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile().getAbsolutePath();
}
return null;
}); });
SwingUtilities.invokeLater(future); SwingUtilities.invokeLater(future);
try { try {
@ -372,7 +429,8 @@ public class UpmBridge {
* 获取系统登录的用户名 * 获取系统登录的用户名
*/ */
@JSBridge @JSBridge
public String getLoginInfo(final JSFunction callback) { @JsAccessible
public String getLoginInfo(final JsObject callback) {
registerLoginInfo(callback); registerLoginInfo(callback);
return MarketConfig.getInstance().getBbsUsername(); return MarketConfig.getInstance().getBbsUsername();
} }
@ -383,8 +441,9 @@ public class UpmBridge {
* @param callback 回调函数 * @param callback 回调函数
*/ */
@JSBridge @JSBridge
public void registerLoginInfo(final JSFunction callback) { @JsAccessible
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); public void registerLoginInfo(final JsObject callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback));
String username = MarketConfig.getInstance().getBbsUsername(); String username = MarketConfig.getInstance().getBbsUsername();
if (StringUtils.isEmpty(username)) { if (StringUtils.isEmpty(username)) {
jsCallback.execute(StringUtils.EMPTY); jsCallback.execute(StringUtils.EMPTY);
@ -404,14 +463,16 @@ public class UpmBridge {
* @param callback 回调函数 * @param callback 回调函数
*/ */
@JSBridge @JSBridge
public void defaultLogin(String username, String password, final JSFunction callback) { @JsAccessible
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new PluginLoginExecutor(username, password)); public void defaultLogin(String username, String password, final JsObject callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new PluginLoginExecutor(username, password));
worker.execute(); worker.execute();
} }
/** /**
* 清除用户信息 * 清除用户信息
*/ */
@JsAccessible
public void clearUserInfo() { public void clearUserInfo() {
MarketConfig.getInstance().setInShowBBsName(StringUtils.EMPTY); MarketConfig.getInstance().setInShowBBsName(StringUtils.EMPTY);
FinePassportManager.getInstance().logout(); FinePassportManager.getInstance().logout();
@ -422,6 +483,7 @@ public class UpmBridge {
* 打开论坛消息界面 * 打开论坛消息界面
*/ */
@JSBridge @JSBridge
@JsAccessible
public void getPriviteMessage() { public void getPriviteMessage() {
try { try {
String loginUrl = CloudCenter.getInstance().acquireUrlByKind("bbs.default"); String loginUrl = CloudCenter.getInstance().acquireUrlByKind("bbs.default");
@ -435,6 +497,7 @@ public class UpmBridge {
* 忘记密码 * 忘记密码
*/ */
@JSBridge @JSBridge
@JsAccessible
public void forgetHref() { public void forgetHref() {
try { try {
Desktop.getDesktop().browse(new URI(CloudCenter.getInstance().acquireUrlByKind("bbs.reset"))); Desktop.getDesktop().browse(new URI(CloudCenter.getInstance().acquireUrlByKind("bbs.reset")));
@ -447,6 +510,7 @@ public class UpmBridge {
* 立即注册 * 立即注册
*/ */
@JSBridge @JSBridge
@JsAccessible
public void registerHref() { public void registerHref() {
try { try {
Desktop.getDesktop().browse(new URI(CloudCenter.getInstance().acquireUrlByKind("bbs.register"))); Desktop.getDesktop().browse(new URI(CloudCenter.getInstance().acquireUrlByKind("bbs.register")));
@ -457,9 +521,11 @@ public class UpmBridge {
/** /**
* 使用系统浏览器打开网页 * 使用系统浏览器打开网页
*
* @param url 要打开的网页 * @param url 要打开的网页
*/ */
@JSBridge @JSBridge
@JsAccessible
public void openShopUrlAtWebBrowser(String url) { public void openShopUrlAtWebBrowser(String url) {
if (Desktop.isDesktopSupported()) { if (Desktop.isDesktopSupported()) {
try { try {

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

@ -58,7 +58,7 @@ public class UpmFinder {
public static void showUPMDialog() { public static void showUPMDialog() {
boolean flag = true; boolean flag = true;
try { try {
Class.forName("com.teamdev.jxbrowser.chromium.Browser"); Class.forName("com.teamdev.jxbrowser.browser.Browser");
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
flag = false; flag = false;
} }

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

@ -6,9 +6,8 @@ import com.fr.design.upm.event.DownloadEvent;
import com.fr.event.Event; import com.fr.event.Event;
import com.fr.event.EventDispatcher; import com.fr.event.EventDispatcher;
import com.fr.event.Listener; import com.fr.event.Listener;
import com.teamdev.jxbrowser.chromium.JSValue; import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import java.awt.*; import java.awt.*;
@ -32,12 +31,10 @@ public class UpmShowPane extends BasicPane {
// 先屏蔽掉这个判断,后续可能修改交互 // 先屏蔽掉这个判断,后续可能修改交互
// if (UpmFinder.checkUPMResourcesExist()) { // if (UpmFinder.checkUPMResourcesExist()) {
modernUIPane = new ModernUIPane.Builder<>() modernUIPane = new ModernUIPane.Builder<>()
.prepare(new ScriptContextAdapter() { .prepare(params -> {
@Override JsObject window = params.frame().executeJavaScript("window");
public void onScriptContextCreated(ScriptContextEvent event) { window.putProperty("PluginHelper", UpmBridge.getBridge());
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); return InjectJsCallback.Response.proceed();
window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser()));
}
}) })
.withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()) .withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap())
.build(); .build();

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

@ -1,8 +1,7 @@
package com.fr.design.upm.exec; package com.fr.design.upm.exec;
import com.fr.design.bridge.exec.JSExecutor; import com.fr.design.bridge.exec.JSExecutor;
import com.teamdev.jxbrowser.chromium.JSFunction; import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.chromium.JSObject;
/** /**
* @author richie * @author richie
@ -11,20 +10,18 @@ import com.teamdev.jxbrowser.chromium.JSObject;
*/ */
public class UpmBrowserExecutor implements JSExecutor { public class UpmBrowserExecutor implements JSExecutor {
public static UpmBrowserExecutor create(JSObject window, JSFunction callback) { public static UpmBrowserExecutor create(JsObject callback) {
return new UpmBrowserExecutor(window, callback); return new UpmBrowserExecutor(callback);
} }
private JSObject window; private JsObject callback;
private JSFunction callback;
private UpmBrowserExecutor(JSObject window, JSFunction callback) { private UpmBrowserExecutor(JsObject callback) {
this.window = window;
this.callback = callback; this.callback = callback;
} }
@Override @Override
public void executor(String newValue) { public void executor(String newValue) {
callback.invoke(window, newValue); callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, newValue);
} }
} }

200
designer-base/src/main/java/com/fr/design/utils/AWTUtilities.java

@ -0,0 +1,200 @@
package com.fr.design.utils;
import sun.awt.SunToolkit;
import java.awt.*;
/**
* 适配jdk10之后被移除的 com.sun.awt.AWTUtilities
* 参照 https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/com/sun/awt/AWTUtilities.java中实现
*
* @author hades
* @version 10.0
* Created by hades on 2020/5/29
*/
public class AWTUtilities {
/**
* @param window the window to set the shape to
* @param shape the shape to set to the window
*
*/
public static void setWindowShape(Window window, Shape shape) {
if (window == null) {
throw new NullPointerException("The window argument should not be null.");
}
window.setShape(shape);
}
/**
*
*
* @param window the window to set the shape to
* @param opaque whether the window must be opaque (true),
* or translucent (false)
*
*/
public static void setWindowOpaque(Window window, boolean opaque) {
if (window == null) {
throw new NullPointerException("The window argument should not be null.");
}
if (!opaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) {
throw new UnsupportedOperationException("The PERPIXEL_TRANSLUCENT translucency kind is not supported");
}
Color color = window.getBackground();
if (color == null) {
color = new Color(0, 0, 0, 0);
}
window.setBackground(new Color(color.getRed(), color.getGreen(), color.getBlue(), opaque ? 255 : 0));
}
public static enum Translucency {
/**
* Represents support in the underlying system for windows each pixel
* of which is guaranteed to be either completely opaque, with
* an alpha value of 1.0, or completely transparent, with an alpha
* value of 0.0.
*/
PERPIXEL_TRANSPARENT,
/**
* Represents support in the underlying system for windows all of
* the pixels of which have the same alpha value between or including
* 0.0 and 1.0.
*/
TRANSLUCENT,
/**
* Represents support in the underlying system for windows that
* contain or might contain pixels with arbitrary alpha values
* between and including 0.0 and 1.0.
*/
PERPIXEL_TRANSLUCENT;
}
/**
* Returns whether the given level of translucency is supported by
* the underlying system.
*
* Note that this method may sometimes return the value
* indicating that the particular level is supported, but
* the native windowing system may still not support the
* given level of translucency (due to the bugs in
* the windowing system).
*
* @param translucencyKind a kind of translucency support
* (either PERPIXEL_TRANSPARENT,
* TRANSLUCENT, or PERPIXEL_TRANSLUCENT)
* @return whether the given translucency kind is supported
*/
private static boolean isTranslucencySupported(Translucency translucencyKind) {
switch (translucencyKind) {
case PERPIXEL_TRANSPARENT:
return isWindowShapingSupported();
case TRANSLUCENT:
return isWindowOpacitySupported();
case PERPIXEL_TRANSLUCENT:
return isWindowTranslucencySupported();
}
return false;
}
/**
* Returns whether the windowing system supports changing the opacity
* value of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* translucency (due to the bugs in the windowing system).
*/
private static boolean isWindowOpacitySupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowOpacitySupported();
}
/**
* Returns whether the windowing system supports changing the shape
* of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* shaping (due to the bugs in the windowing system).
*/
private static boolean isWindowShapingSupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowShapingSupported();
}
private static boolean isWindowTranslucencySupported() {
/*
* Per-pixel alpha is supported if all the conditions are TRUE:
* 1. The toolkit is a sort of SunToolkit
* 2. The toolkit supports translucency in general
* (isWindowTranslucencySupported())
* 3. There's at least one translucency-capable
* GraphicsConfiguration
*/
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) {
return false;
}
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
// If the default GC supports translucency return true.
// It is important to optimize the verification this way,
// see CR 6661196 for more details.
if (isTranslucencyCapable(env.getDefaultScreenDevice()
.getDefaultConfiguration()))
{
return true;
}
// ... otherwise iterate through all the GCs.
GraphicsDevice[] devices = env.getScreenDevices();
for (int i = 0; i < devices.length; i++) {
GraphicsConfiguration[] configs = devices[i].getConfigurations();
for (int j = 0; j < configs.length; j++) {
if (isTranslucencyCapable(configs[j])) {
return true;
}
}
}
return false;
}
private static boolean isTranslucencyCapable(GraphicsConfiguration gc) {
if (gc == null) {
throw new NullPointerException("The gc argument should not be null");
}
/*
return gc.isTranslucencyCapable();
*/
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isTranslucencyCapable(gc);
}
}

3
designer-base/src/main/java/com/fr/start/SplashWindow.java

@ -2,9 +2,9 @@ package com.fr.start;
import com.fr.base.BaseUtils; import com.fr.base.BaseUtils;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
import com.fr.design.utils.AWTUtilities;
import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.OperatingSystem; import com.fr.stable.OperatingSystem;
import com.sun.awt.AWTUtilities;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JFrame; import javax.swing.JFrame;
@ -41,7 +41,6 @@ public class SplashWindow extends JFrame {
this.setAlwaysOnTop(false); this.setAlwaysOnTop(false);
this.setUndecorated(true); this.setUndecorated(true);
AWTUtilities.setWindowOpaque(this, false); AWTUtilities.setWindowOpaque(this, false);
//使窗体背景透明 //使窗体背景透明
if (OperatingSystem.isWindows()) { if (OperatingSystem.isWindows()) {
this.setBackground(new Color(0, 0, 0, 0)); this.setBackground(new Color(0, 0, 0, 0));

41
designer-base/src/test/java/com/fr/design/gui/icombocheckbox/UICheckListPopupTest.java

@ -0,0 +1,41 @@
package com.fr.design.gui.icombocheckbox;
import junit.framework.TestCase;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* @author hades
* @version 10.0
* Created by hades on 2020/4/3
*/
public class UICheckListPopupTest extends TestCase {
@Test
public void testGetSelectedValues() {
Object[] values = new Object[]{"a", "b", "c"};
Map<Object, Boolean> map = new TreeMap<>();
map.put("a", true);
map.put("b", false);
map.put("c", true);
List<Object> list = new ArrayList<>();
for (Map.Entry<Object, Boolean> entry : map.entrySet()) {
if (entry.getValue()) {
list.add(entry.getKey());
}
}
Object[] selectValues = list.toArray();
UICheckListPopup uiCheckListPopup1 = new UICheckListPopup(values);
uiCheckListPopup1.setSelectedValue(map);
Assert.assertArrayEquals(selectValues, uiCheckListPopup1.getSelectedValues());
UICheckListPopup uiCheckListPopup2 = new UICheckListPopup(values, false);
uiCheckListPopup2.setSelectedValue(map);
Assert.assertArrayEquals(selectValues, uiCheckListPopup2.getSelectedValues());
}
}

3
designer-chart/build.gradle

@ -0,0 +1,3 @@
dependencies {
compile project(':designer-base')
}

3
designer-form/build.gradle

@ -0,0 +1,3 @@
dependencies {
compile project(':designer-base')
}

4
designer-realize/build.gradle

@ -0,0 +1,4 @@
dependencies {
compile project(':designer-form')
compile project(':designer-chart')
}

2
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/listener/ComponentHandler.java

@ -1,6 +1,6 @@
package com.fr.design.mainframe.alphafine.listener; package com.fr.design.mainframe.alphafine.listener;
import com.sun.awt.AWTUtilities; import com.fr.design.utils.AWTUtilities;
import java.awt.*; import java.awt.*;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;

29
globalConfigHook.gradle

@ -0,0 +1,29 @@
def getRootGradle() {
def currentGradle = gradle
while (currentGradle.parent) {
currentGradle = currentGradle.parent
}
return currentGradle
}
def findHookIncludedBuild() {
def rootGradle = getRootGradle()
def hookProject = rootGradle.getIncludedBuilds()
.find({ build -> build.name == 'hook' })
return hookProject
}
def findGlobalConfig() {
def hookProject = findHookIncludedBuild()
if (hookProject) {
def path = hookProject.projectDir.parent + '/globalConfig.gradle'
if (file(path).exists()) {
return path
}
}
}
def globalConfigPath = findGlobalConfig()
if (globalConfigPath) {
apply from: globalConfigPath
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored

Binary file not shown.

6
gradle/wrapper/gradle-wrapper.properties vendored

@ -0,0 +1,6 @@
#Wed Apr 22 15:17:12 CST 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

172
gradlew vendored

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

4
pom.xml

@ -28,8 +28,8 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version> <version>3.1</version>
<configuration> <configuration>
<source>1.7</source> <source>1.8</source>
<target>1.7</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

12
settings.gradle

@ -0,0 +1,12 @@
pluginManagement {
repositories {
maven {
url 'http://mvn.finedevelop.com/repository/maven-public/'
}
gradlePluginPortal()
}
}
rootProject.name = 'design'
include 'designer-base', 'designer-chart', 'designer-form', 'designer-realize'
Loading…
Cancel
Save