Browse Source

Merge pull request #8921 in DESIGN/design from release/10.0 to final/10.0

* commit 'd84f7a9b05acad1ddff2c8246f534a260fb384e0':
  REPORT-69532 10.0创建复用组件超出960*540时,给出提示
  REPORT-67417 运营产品v1.0  bug patch
  REPORT-67417 运营产品v1.0 同步一份到10.0
  REPORT-71425 websocket断开优化 同步到10.0.19.13
  REPORT-69285 数据连接安全关键字检查拦截
  REPORT-69285 数据连接安全关键字检查拦截
  REPORT-69285 数据连接安全关键字检查拦截
  REPORT-70011 国际化适配
  REPORT-68607 数据连接配置操作放事务
final/10.0
superman 3 years ago
parent
commit
0aac39936a
  1. 115
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java
  2. 55
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java
  3. 44
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineShortCutUtil.java
  4. 30
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/SizedStack.java
  5. 22
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  6. 33
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  7. 7
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java
  8. 2
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionShowPane.java
  9. 15
      designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java
  10. 22
      designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java
  11. 24
      designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java
  12. 28
      designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java
  13. 28
      designer-base/src/main/java/com/fr/design/utils/SvgPaintUtils.java
  14. 23
      designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java
  15. 77
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java
  16. 57
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java
  17. 23
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineHelper.java
  18. 77
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java
  19. 50
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java
  20. 6
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java
  21. 832
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java
  22. 84
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java
  23. 2
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFinePane.java
  24. 19
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineTextField.java
  25. 68
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipContentCellRender.java
  26. 42
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipList.java
  27. 62
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaSearchTooltipPane.java
  28. 32
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/LineCellRender.java
  29. 100
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsContentCellRender.java
  30. 79
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsImagePanel.java
  31. 78
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java
  32. 36
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsSearchResultPane.java
  33. 126
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchListModel.java
  34. 83
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultContentCellRender.java
  35. 51
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultPane.java
  36. 58
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchTooltipPopup.java
  37. 81
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SelectedLabel.java
  38. 14
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/exception/AlphaFineNetworkException.java
  39. 200
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java
  40. 121
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/DefaultProductNewsPane.java
  41. 167
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/HelpDocumentNoResultPane.java
  42. 167
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/LoadingRightSearchResultPane.java
  43. 69
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NetWorkFailedPane.java
  44. 23
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultPane.java
  45. 63
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultWithLinkPane.java
  46. 14
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/ResultShowPane.java
  47. 27
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SearchLoadingPane.java
  48. 32
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SimpleRightSearchResultPane.java
  49. 60
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java
  50. 84
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionWindow.java
  51. 127
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/ProductNewsSearchWorkerManager.java
  52. 17
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchManager.java
  53. 37
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchTextBean.java
  54. 146
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchWorkerManager.java
  55. 12
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/fun/AlphaFineSearchProvider.java
  56. 7
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java
  57. 13
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java
  58. 7
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java
  59. 11
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/PluginSearchManager.java
  60. 123
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java
  61. 138
      designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java
  62. 26
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java
  63. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/blue_bulb.svg
  64. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bulb.svg
  65. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/clear.svg
  66. 3
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/close.svg
  67. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group.svg
  68. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group_new.svg
  69. 3
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg
  70. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/history_search.svg
  71. 3
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/hot_search.svg
  72. 3
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/minimize.svg

115
designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java

@ -1,5 +1,6 @@
package com.fr.design.actions.help.alphafine;
import com.fr.design.DesignerEnvManager;
import com.fr.general.ComparatorUtils;
import com.fr.license.function.VT4FR;
import com.fr.stable.OperatingSystem;
@ -8,6 +9,12 @@ import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLReadable;
import com.fr.stable.xml.XMLable;
import com.fr.stable.xml.XMLableReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@ -82,9 +89,28 @@ public class AlphaFineConfigManager implements XMLable {
*/
private boolean needRemind = true;
/**
* 产品动态
*/
private boolean productDynamics = true;
private Map<String, String> actionSearchTextCache = new HashMap<>(8);
private String cacheBuildNO;
/**
* key: 登录的bbs用户
* value: alphaFine历史搜索记录
*/
private Map<String, Stack<String>> historySearchMap = new LinkedHashMap<>();
/**
* key: 登录的bbs用户
* value: 已读的cid的集合
*/
private Map<String, Set<Long>> readSetMap = new LinkedHashMap<>();
/**
* 直接操作菜单次数
*/
@ -120,12 +146,17 @@ public class AlphaFineConfigManager implements XMLable {
this.setContainFileContent(reader.getAttrAsBoolean("isContainFileContent", false));
this.setNeedSegmentationCheckbox(reader.getAttrAsBoolean("needSegmentationCheckbox", true));
this.setNeedIntelligentCustomerService(reader.getAttrAsBoolean("needIntelligentCustomerService", true));
this.setProductDynamics(reader.getAttrAsBoolean("productDynamics", true));
this.setShortcuts(reader.getAttrAsString("shortcuts", getDefaultShortCuts()));
this.setNeedRemind(reader.getAttrAsBoolean("isNeedRemind", true));
this.setOperateCount(reader.getAttrAsInt("operateCount", 0));
} else if (reader.isChildNode()) {
if (ComparatorUtils.equals(reader.getTagName(), "ActionSearchTextCache")) {
readActionSearchTextCacheXML(reader);
} else if ("SearchHistory".equals(reader.getTagName())) {
readHistorySearch(reader);
} else if ("ReadSet".equals(reader.getTagName())) {
readReadSet(reader);
}
}
}
@ -152,6 +183,53 @@ public class AlphaFineConfigManager implements XMLable {
});
}
private void readHistorySearch(XMLableReader reader) {
reader.readXMLObject(new XMLReadable() {
@Override
public void readXML(XMLableReader xmLableReader) {
if (ComparatorUtils.equals(reader.getTagName(), "history")) {
String tmpVal = reader.getElementValue();
if (tmpVal != null) {
tmpVal = tmpVal.replace("[",StringUtils.EMPTY).replace("]",StringUtils.EMPTY);
Stack<String> stack = new SizedStack<>(3);
String[] historyList = tmpVal.split(",");
for (String history : historyList) {
String value = history.trim();
if (StringUtils.isNotEmpty(value)) {
stack.add(value);
}
}
historySearchMap.put(reader.getAttrAsString("user", StringUtils.EMPTY), stack);
}
}
}
});
}
private void readReadSet(XMLableReader reader) {
reader.readXMLObject(new XMLReadable() {
@Override
public void readXML(XMLableReader xmLableReader) {
if (ComparatorUtils.equals(reader.getTagName(), "readId")) {
String tmpVal = reader.getElementValue();
if (tmpVal != null) {
tmpVal = tmpVal.replace("[",StringUtils.EMPTY).replace("]",StringUtils.EMPTY);
String[] idArr = tmpVal.split(",");
Set<Long> setId = new HashSet<>();
for (String id : idArr) {
String value = id.trim();
if (StringUtils.isNotEmpty(value)) {
setId.add(Long.parseLong(value));
}
}
readSetMap.put(reader.getAttrAsString("user", StringUtils.EMPTY), setId);
}
}
}
});
}
@Override
public void writeXML(XMLPrintWriter writer) {
writer.startTAG("AlphaFineConfigManager");
@ -167,8 +245,11 @@ public class AlphaFineConfigManager implements XMLable {
.attr("isNeedRemind", this.isNeedRemind())
.attr("operateCount", this.getOperateCount())
.attr("needSegmentationCheckbox", this.isNeedSegmentationCheckbox())
.attr("needIntelligentCustomerService", this.isNeedIntelligentCustomerService());
.attr("needIntelligentCustomerService", this.isNeedIntelligentCustomerService())
.attr("productDynamics", this.isProductDynamics());
writeActionSearchTextCacheXML(writer);
writeSearchHistory(writer);
writeReadSet(writer);
writer.end();
}
@ -183,6 +264,22 @@ public class AlphaFineConfigManager implements XMLable {
writer.end();
}
private void writeSearchHistory(XMLPrintWriter writer) {
writer.startTAG("SearchHistory");
for (Map.Entry<String, Stack<String>> entry : historySearchMap.entrySet()) {
writer.startTAG("history").attr("user", entry.getKey()).textNode(entry.getValue().toString()).end();
}
writer.end();
}
private void writeReadSet(XMLPrintWriter writer) {
writer.startTAG("ReadSet");
for (Map.Entry<String, Set<Long>> entry : readSetMap.entrySet()) {
writer.startTAG("readId").attr("user", entry.getKey()).textNode(entry.getValue().toString()).end();
}
writer.end();
}
public boolean isSearchOnLine() {
return searchOnLine;
}
@ -335,4 +432,20 @@ public class AlphaFineConfigManager implements XMLable {
public void setCacheBuildNO(@NotNull String cacheBuildNO) {
this.cacheBuildNO = cacheBuildNO;
}
public Stack<String> getHistorySearch() {
return historySearchMap.computeIfAbsent(DesignerEnvManager.getEnvManager().getDesignerLoginUsername(), k -> new SizedStack<>(3));
}
public Set<Long> getReadSet() {
return readSetMap.computeIfAbsent(DesignerEnvManager.getEnvManager().getDesignerLoginUsername(), k -> new HashSet<>());
}
public boolean isProductDynamics() {
return productDynamics;
}
public void setProductDynamics(boolean productDynamics) {
this.productDynamics = productDynamics;
}
}

55
designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java

@ -25,37 +25,12 @@ import java.awt.event.MouseEvent;
public class AlphaFineConfigPane extends BasicPane {
private static final String TYPE = "pressed";
private static final String DISPLAY_TYPE = "+";
private static final String BACK_SLASH = "BACK_SLASH";
private static final String DISPLAY_BACK_SLASH = "\\";
private static final String SLASH = "SLASH";
private static final String DISPLAY_SLASH = "/";
private static final String CONTROL = "CONTROL";
private static final String DISPLAY_CONTROL = "ctrl";
private static final String OPEN_BRACKET = "OPEN_BRACKET";
private static final String DISPLAY_OPEN_BRACKET = "{";
private static final String CLOSE_BRACKET = "CLOSE_BRACKET";
private static final String DISPLAY_CLOSE_BRACKET = "}";
private static final String COMMA = "COMMA";
private static final String DISPLAY_COMMA = ",";
private static final String PERIOD = "PERIOD";
private static final String DISPLAY_PERIOD = ".";
private static final String SEMICOLON = "SEMICOLON";
private static final String DISPLAY_SEMICOLON = ";";
private static final String QUOTE = "QUOTE";
private static final String DISPLAY_QUOTE = "'";
private static final String EQUALS = "EQUALS";
private static final String DISPLAY_EQUALS = "+";
private static final String MINUS = "MINUS";
private static final String DISPLAY_MINUS = "-";
private static final String COMMAND = "META";
private static final String SMALL_COMMAND = "meta";
private static final String DISPLAY_COMMAND = "\u2318";
private static final double COLUMN_GAP = 180;
private static final double ROW_GAP = 25;
private KeyStroke shortCutKeyStore = null;
private UICheckBox enabledCheckbox, searchOnlineCheckbox, needSegmentationCheckbox, needIntelligentCustomerService, containRecommendCheckbox, containActionCheckbox, containDocumentCheckbox, containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox;
private UICheckBox enabledCheckbox, searchOnlineCheckbox, needSegmentationCheckbox, needIntelligentCustomerService, productDynamicsCheckbox, containActionCheckbox, containDocumentCheckbox, containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox;
private UITextField shortcutsField;
public AlphaFineConfigPane() {
@ -75,9 +50,8 @@ public class AlphaFineConfigPane extends BasicPane {
private Component[][] initSearchRangeComponents() {
Component[][] components = new Component[][]{
new Component[]{containRecommendCheckbox, containActionCheckbox, containDocumentCheckbox},
new Component[]{productDynamicsCheckbox, containActionCheckbox, containDocumentCheckbox},
new Component[]{containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox},
new Component[]{needIntelligentCustomerService, null, null}
};
return components;
}
@ -95,7 +69,7 @@ public class AlphaFineConfigPane extends BasicPane {
double[] columnSize = {COLUMN_GAP, COLUMN_GAP, COLUMN_GAP};
JPanel northPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_Search_Range"));
containRecommendCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_Recommend"));
productDynamicsCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_Dynamics"));
containActionCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set"));
containPluginCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon"));
containDocumentCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help"));
@ -139,7 +113,7 @@ public class AlphaFineConfigPane extends BasicPane {
int keyCode = e.getKeyCode();
shortCutKeyStore = KeyStroke.getKeyStroke(keyCode, modifier);
String str = shortCutKeyStore.toString();
shortcutsField.setText(getDisplayShortCut(str));
shortcutsField.setText(AlphaFineShortCutUtil.getDisplayShortCut(str));
shortcutsField.selectAll();
}
});
@ -153,16 +127,16 @@ public class AlphaFineConfigPane extends BasicPane {
@Override
public void actionPerformed(ActionEvent e) {
if (!searchOnlineCheckbox.isSelected()) {
containRecommendCheckbox.setEnabled(false);
productDynamicsCheckbox.setEnabled(false);
containPluginCheckbox.setEnabled(false);
containDocumentCheckbox.setEnabled(false);
needIntelligentCustomerService.setEnabled(false);
containRecommendCheckbox.setSelected(false);
productDynamicsCheckbox.setSelected(false);
containPluginCheckbox.setSelected(false);
containDocumentCheckbox.setSelected(false);
needIntelligentCustomerService.setSelected(false);
} else {
containRecommendCheckbox.setEnabled(true);
productDynamicsCheckbox.setEnabled(true);
containPluginCheckbox.setEnabled(true);
containDocumentCheckbox.setEnabled(true);
needIntelligentCustomerService.setEnabled(true);
@ -207,10 +181,10 @@ public class AlphaFineConfigPane extends BasicPane {
this.containPluginCheckbox.setSelected(alphaFineConfigManager.isContainPlugin() && enabled4Locale);
this.containPluginCheckbox.setEnabled(enabled4Locale);
this.containRecommendCheckbox.setSelected(alphaFineConfigManager.isContainRecommend() && enabled4Locale);
this.containRecommendCheckbox.setEnabled(enabled4Locale);
this.productDynamicsCheckbox.setSelected(alphaFineConfigManager.isProductDynamics() && enabled4Locale);
this.productDynamicsCheckbox.setEnabled(enabled4Locale);
this.shortcutsField.setText(getDisplayShortCut(alphaFineConfigManager.getShortcuts()));
this.shortcutsField.setText(AlphaFineShortCutUtil.getDisplayShortCut(alphaFineConfigManager.getShortcuts()));
this.needSegmentationCheckbox.setSelected(alphaFineConfigManager.isNeedSegmentationCheckbox());
@ -226,7 +200,7 @@ public class AlphaFineConfigPane extends BasicPane {
alphaFineConfigManager.setContainPlugin(this.containPluginCheckbox.isSelected());
alphaFineConfigManager.setContainAction(this.containActionCheckbox.isSelected());
alphaFineConfigManager.setContainDocument(this.containDocumentCheckbox.isSelected());
alphaFineConfigManager.setContainRecommend(this.containRecommendCheckbox.isSelected());
alphaFineConfigManager.setProductDynamics(this.productDynamicsCheckbox.isSelected());
alphaFineConfigManager.setEnabled(this.enabledCheckbox.isSelected());
alphaFineConfigManager.setSearchOnLine(this.searchOnlineCheckbox.isSelected());
alphaFineConfigManager.setContainTemplate(this.containTemplateCheckbox.isSelected());
@ -245,13 +219,6 @@ public class AlphaFineConfigPane extends BasicPane {
}
private String getDisplayShortCut(String shortCut) {
return shortCut.replace(TYPE, DISPLAY_TYPE).replace(BACK_SLASH, DISPLAY_BACK_SLASH).replace(SLASH, DISPLAY_SLASH)
.replace(CONTROL, DISPLAY_CONTROL).replace(OPEN_BRACKET, DISPLAY_OPEN_BRACKET).replace(CLOSE_BRACKET, DISPLAY_CLOSE_BRACKET)
.replace(COMMA, DISPLAY_COMMA).replace(PERIOD, DISPLAY_PERIOD).replace(SEMICOLON, DISPLAY_SEMICOLON).replace(QUOTE, DISPLAY_QUOTE)
.replace(EQUALS, DISPLAY_EQUALS).replace(MINUS, DISPLAY_MINUS).replace(COMMAND, DISPLAY_COMMAND).replace(SMALL_COMMAND, DISPLAY_COMMAND);
}
private KeyStroke convert2KeyStroke(String ks) {
return KeyStroke.getKeyStroke(ks.replace(DISPLAY_TYPE, TYPE));

44
designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineShortCutUtil.java

@ -0,0 +1,44 @@
package com.fr.design.actions.help.alphafine;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/26
*/
public class AlphaFineShortCutUtil {
private static final String TYPE = "pressed";
private static final String DISPLAY_TYPE = "+";
private static final String BACK_SLASH = "BACK_SLASH";
private static final String DISPLAY_BACK_SLASH = "\\";
private static final String SLASH = "SLASH";
private static final String DISPLAY_SLASH = "/";
private static final String CONTROL = "CONTROL";
private static final String DISPLAY_CONTROL = "ctrl";
private static final String OPEN_BRACKET = "OPEN_BRACKET";
private static final String DISPLAY_OPEN_BRACKET = "{";
private static final String CLOSE_BRACKET = "CLOSE_BRACKET";
private static final String DISPLAY_CLOSE_BRACKET = "}";
private static final String COMMA = "COMMA";
private static final String DISPLAY_COMMA = ",";
private static final String PERIOD = "PERIOD";
private static final String DISPLAY_PERIOD = ".";
private static final String SEMICOLON = "SEMICOLON";
private static final String DISPLAY_SEMICOLON = ";";
private static final String QUOTE = "QUOTE";
private static final String DISPLAY_QUOTE = "'";
private static final String EQUALS = "EQUALS";
private static final String DISPLAY_EQUALS = "+";
private static final String MINUS = "MINUS";
private static final String DISPLAY_MINUS = "-";
private static final String COMMAND = "META";
private static final String SMALL_COMMAND = "meta";
private static final String DISPLAY_COMMAND = "\u2318";
public static String getDisplayShortCut(String shortCut) {
return shortCut.replace(TYPE, DISPLAY_TYPE).replace(BACK_SLASH, DISPLAY_BACK_SLASH).replace(SLASH, DISPLAY_SLASH)
.replace(CONTROL, DISPLAY_CONTROL).replace(OPEN_BRACKET, DISPLAY_OPEN_BRACKET).replace(CLOSE_BRACKET, DISPLAY_CLOSE_BRACKET)
.replace(COMMA, DISPLAY_COMMA).replace(PERIOD, DISPLAY_PERIOD).replace(SEMICOLON, DISPLAY_SEMICOLON).replace(QUOTE, DISPLAY_QUOTE)
.replace(EQUALS, DISPLAY_EQUALS).replace(MINUS, DISPLAY_MINUS).replace(COMMAND, DISPLAY_COMMAND).replace(SMALL_COMMAND, DISPLAY_COMMAND);
}
}

30
designer-base/src/main/java/com/fr/design/actions/help/alphafine/SizedStack.java

@ -0,0 +1,30 @@
package com.fr.design.actions.help.alphafine;
import java.util.Stack;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/23
*/
public class SizedStack<T> extends Stack<T> {
private final int maxSize;
public SizedStack(int size) {
super();
this.maxSize = size;
}
@Override
public T push(T object) {
while (this.size() >= maxSize) {
this.remove(0);
}
// 不重复
if (this.contains(object)) {
return object;
}
return super.push(object);
}
}

22
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java

@ -8,10 +8,12 @@ import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.server.ConnectionListAction;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.editlock.ConnectionLockChangeChecker;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UILockButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.file.ConnectionConfig;
import com.fr.report.LockItem;
@ -22,6 +24,7 @@ import com.fr.transaction.WorkerFacade;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.connection.DBConnectAuth;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
@ -32,6 +35,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 选择数据连接的下拉框
@ -145,10 +149,16 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
connectionListDialog.setDoOKSucceed(false);
return;
}
AtomicBoolean saved = new AtomicBoolean(true);
Configurations.modify(new WorkerFacade(ConnectionConfig.class) {
@Override
public void run() {
connectionListPane.update(connectionConfig);
try {
connectionListPane.update(connectionConfig);
} catch (Exception e) {
saved.set(false);
FineJOptionPane.showMessageDialog(connectionListPane, e.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE);
}
}
}.addCallBack(new CallBackAdaptor() {
@Override
@ -159,9 +169,13 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
@Override
public void afterCommit() {
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 关闭定义数据连接页面,为其解锁
EditLockUtils.unlock(LockItem.CONNECTION);
if (saved.get()) {
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 定义数据连接弹窗关闭后,解锁
EditLockUtils.unlock(LockItem.CONNECTION);
} else {
connectionListDialog.setDoOKSucceed(false);
}
}
}));

33
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java

@ -1,5 +1,6 @@
package com.fr.design.data.datapane.connect;
import com.fr.data.core.db.JDBCSecurityChecker;
import com.fr.data.impl.Connection;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
@ -22,6 +23,7 @@ import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import javax.swing.SwingUtilities;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -157,24 +159,49 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
/**
* Update.
*/
public void update(ConnectionConfig connectionConfig) {
public void update(ConnectionConfig connectionConfig) throws Exception {
// Nameable[]居然不能强转成NameObject[],一定要这么写...
Nameable[] res = this.update();
Map<String, Connection> updatedMap = new LinkedHashMap<>();
Arrays.stream(res).map(n -> (NameObject) n).forEach(no -> updatedMap.put(no.getName(), (Connection) no.getObject()));
List<String> removedConnNames = new ArrayList<>();
Map<String, Connection> addedOrUpdatedConnections = new LinkedHashMap<>();
MapCompareUtils.contrastMapEntries(populatedConnectionsSnapshot, updatedMap, (entryEventKind, s, connection) -> {
switch (entryEventKind) {
case REMOVED:
connectionConfig.removeConnection(s);
removedConnNames.add(s);
break;
case ADDED:
case UPDATED:
connectionConfig.addConnection(s, connection);
addedOrUpdatedConnections.put(s, connection);
default:
break;
}
});
this.checkSecurity(addedOrUpdatedConnections);
alterConnections(removedConnNames, addedOrUpdatedConnections);
}
private void alterConnections(List<String> removedConnNames, Map<String, Connection> addedOrUpdatedConnections) {
removedConnNames.forEach(n -> ConnectionConfig.getInstance().removeConnection(n));
addedOrUpdatedConnections.forEach((name, conn) -> ConnectionConfig.getInstance().addConnection(name, conn));
}
private void checkSecurity(Map<String, Connection> addedOrUpdatedConnections) throws Exception {
for (Map.Entry<String, Connection> entry : addedOrUpdatedConnections.entrySet()) {
Connection connection = entry.getValue();
if (connection instanceof JDBCDatabaseConnection) {
try {
JDBCSecurityChecker.checkURL(((JDBCDatabaseConnection) connection).getURL());
JDBCSecurityChecker.checkValidationQuery(((JDBCDatabaseConnection) connection).getDbcpAttr().getValidationQuery());
} catch (SQLException e) {
throw new SQLException(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Invalid_Config", entry.getKey()) + ", " + e.getMessage(), e.getCause());
}
}
}
}
@Override

7
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java

@ -4,9 +4,8 @@ import com.fr.design.gui.frpane.LoadingBasicPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.file.ConnectionConfig;
import javax.swing.*;
import java.awt.*;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.util.HashMap;
public class ConnectionManagerPane extends LoadingBasicPane implements ConnectionShowPane {
@ -39,7 +38,7 @@ public class ConnectionManagerPane extends LoadingBasicPane implements Connectio
this.connectionListPane.populate(datasourceManager);
}
public void update(ConnectionConfig datasourceManager) {
public void update(ConnectionConfig datasourceManager) throws Exception {
this.connectionListPane.update(datasourceManager);
}

2
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionShowPane.java

@ -7,7 +7,7 @@ import com.fr.file.ConnectionConfig;
* 数据链接显示面板
*/
public interface ConnectionShowPane {
void update(ConnectionConfig connectionConfig);
void update(ConnectionConfig connectionConfig) throws Exception;
void populate(ConnectionConfig connectionConfig);

15
designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java

@ -37,15 +37,19 @@ public class MessageWithLink extends JEditorPane {
}
public MessageWithLink(String frontMessage, String linkName, String link, String backMessage) {
this(frontMessage, linkName, link, backMessage, LABEL.getBackground(), LABEL.getFont());
this(frontMessage, linkName, link, backMessage, LABEL.getBackground(), LABEL.getFont(), LABEL.getForeground());
}
public MessageWithLink(String message, String linkName, String link, Color color, Font font) {
this(message, linkName, link, StringUtils.EMPTY, color, font);
this(message, linkName, link, StringUtils.EMPTY, color, font, LABEL.getForeground());
}
public MessageWithLink(String frontMessage, String linkName, String link, String backMessage, Color color, Font font) {
super("text/html", "<html><body style=\"" + generateStyle(color, font) + "\">" + frontMessage + "<a href=\"" + link + "\">" + linkName + "</a>" + backMessage + "</body></html>");
this(frontMessage, linkName, link, backMessage, color, font, LABEL.getForeground());
}
public MessageWithLink(String frontMessage, String linkName, String link, String backMessage, Color backgroundColor, Font font, Color fontColor) {
super("text/html", "<html><body style=\"" + generateStyle(backgroundColor, font, fontColor) + "\">" + frontMessage + "<a href=\"" + link + "\">" + linkName + "</a>" + backMessage + "</body></html>");
initListener(link);
setEditable(false);
setBorder(null);
@ -66,12 +70,13 @@ public class MessageWithLink extends JEditorPane {
});
}
private static StringBuilder generateStyle(Color color, Font font) {
private static StringBuilder generateStyle(Color backgroundColor, Font font, Color fontColor) {
// 构建相同风格样式
StringBuilder style = new StringBuilder("font-family:" + font.getFamily() + ";");
style.append("font-weight:").append(font.isBold() ? "bold" : "normal").append(";");
style.append("font-size:").append(font.getSize()).append("pt;");
style.append("background-color: rgb(").append(color.getRed()).append(",").append(color.getGreen()).append(",").append(color.getBlue()).append(");");
style.append("color:rgb(").append(fontColor.getRed()).append(",").append(fontColor.getGreen()).append(",").append(fontColor.getBlue()).append(");");
style.append("background-color: rgb(").append(backgroundColor.getRed()).append(",").append(backgroundColor.getGreen()).append(",").append(backgroundColor.getBlue()).append(");");
return style;
}

22
designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java

@ -6,17 +6,17 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.stable.Constants;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Window;
/**
* Created by kerry on 5/6/21
@ -31,6 +31,13 @@ public class DesignerToastMsgUtil {
}
public static ToastMsgDialog createPromptDialog(String text) {
return createDialog(PROMPT_ICON, toastPane(text), DesignerContext.getDesignerFrame());
}
public static ToastMsgDialog createPromptDialog(JPanel contentPane) {
return createDialog(PROMPT_ICON, contentPane, DesignerContext.getDesignerFrame());
}
public static void toastPrompt(JPanel contendPane) {
toastPane(PROMPT_ICON, contendPane, DesignerContext.getDesignerFrame());
@ -69,6 +76,11 @@ public class DesignerToastMsgUtil {
}
private static void toastPane(Icon icon, JPanel contendPane, Window parent) {
ToastMsgDialog dialog = createDialog(icon, contendPane, parent);
dialog.setVisible(true);
}
private static ToastMsgDialog createDialog(Icon icon, JPanel contendPane, Window parent) {
JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane();
UILabel uiLabel = new UILabel(icon);
uiLabel.setVerticalAlignment(SwingConstants.TOP);
@ -83,7 +95,7 @@ public class DesignerToastMsgUtil {
} else {
dialog = new ToastMsgDialog((Frame) parent, pane);
}
dialog.setVisible(true);
return dialog;
}
@ -118,4 +130,4 @@ public class DesignerToastMsgUtil {
.toString();
}
}
}

24
designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java

@ -3,10 +3,11 @@ package com.fr.design.mainframe.toast;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.dialog.UIDialog;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.module.ModuleContext;
import java.awt.Dialog;
import javax.swing.JPanel;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Point;
@ -24,6 +25,7 @@ public class ToastMsgDialog extends UIDialog {
private ScheduledExecutorService TIMER;
private int hide_height = 0;
private JPanel contentPane;
private boolean show = false;
public ToastMsgDialog(Frame parent, JPanel panel) {
super(parent);
@ -50,12 +52,16 @@ public class ToastMsgDialog extends UIDialog {
hide_height = dimension.height;
setSize(new Dimension(dimension.width, 0));
contentPane.setSize(dimension);
setLocationRelativeTo(DesignerContext.getDesignerFrame().getContentFrame());
int positionY = DesignerContext.getDesignerFrame().getContentFrame().getLocationOnScreen().y + 10;
setLocation((DesignerContext.getDesignerFrame().getWidth() - dimension.width) / 2, positionY);
setRelativeLocation(dimension);
addMouseEvent(contentPane);
}
private void setRelativeLocation(Dimension dimension) {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
int positionX = designerFrame.getLocationOnScreen().x + (designerFrame.getWidth() - dimension.width) / 2;
int positionY = designerFrame.getContentFrame().getLocationOnScreen().y + 10;
this.setLocation(positionX, positionY);
}
private Dimension calculatePreferSize() {
Dimension contentDimension = contentPane.getPreferredSize();
@ -65,6 +71,7 @@ public class ToastMsgDialog extends UIDialog {
public void display(JPanel outerJPanel) {
show = true;
outerJPanel.setLocation(0, -hide_height);
ScheduledExecutorService TIP_TOOL_TIMER = createToastScheduleExecutorService();
TIP_TOOL_TIMER.scheduleAtFixedRate(new Runnable() {
@ -98,12 +105,13 @@ public class ToastMsgDialog extends UIDialog {
TIP_TOOL_TIMER.shutdown();
ToastMsgDialog.this.setVisible(false);
ToastMsgDialog.this.dispose();
ToastMsgDialog.this.show = false;
}
outerJPanel.setLocation(point.x, point.y - 5);
Dimension dimension = ToastMsgDialog.this.getSize();
ToastMsgDialog.this.setSize(new Dimension(dimension.width, dimension.height - 5));
}
}, 0,50, TimeUnit.MILLISECONDS);
}, 0, 50, TimeUnit.MILLISECONDS);
}
}, 5000, TimeUnit.MILLISECONDS);
@ -159,5 +167,7 @@ public class ToastMsgDialog extends UIDialog {
super.dispose();
}
}
public boolean isShow() {
return show;
}
}

28
designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java

@ -3,19 +3,26 @@ package com.fr.design.os.impl;
import com.fr.design.data.datapane.connect.ConnectionManagerPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.file.ConnectionConfig;
import com.fr.report.LockItem;
import com.fr.stable.os.support.OSBasedAction;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.report.LockItem;
import javax.swing.JOptionPane;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.fr.design.actions.server.ConnectionListAction.doWithDatasourceManager;
/**
* 数据连接窗口
*
* @author pengda
* @date 2019/10/9
*/
@ -52,10 +59,17 @@ public class DatabaseDialogAction implements OSBasedAction {
databaseListDialog.setDoOKSucceed(false);
return;
}
AtomicBoolean saved = new AtomicBoolean(true);
Configurations.modify(new WorkerFacade(ConnectionConfig.class) {
@Override
public void run() {
databaseManagerPane.update(datasourceManager);
try {
databaseManagerPane.update(datasourceManager);
} catch (Exception e) {
saved.set(false);
FineJOptionPane.showMessageDialog(databaseManagerPane, e.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE);
}
}
}.addCallBack(new CallBackAdaptor() {
@Override
@ -66,9 +80,13 @@ public class DatabaseDialogAction implements OSBasedAction {
@Override
public void afterCommit() {
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 定义数据连接弹窗关闭后,解锁
EditLockUtils.unlock(LockItem.CONNECTION);
if (saved.get()) {
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 定义数据连接弹窗关闭后,解锁
EditLockUtils.unlock(LockItem.CONNECTION);
} else {
databaseListDialog.setDoOKSucceed(false);
}
}
}));
}

28
designer-base/src/main/java/com/fr/design/utils/SvgPaintUtils.java

@ -0,0 +1,28 @@
package com.fr.design.utils;
import com.fr.base.svg.SVGIcon;
import com.fr.base.svg.SystemScaleUtils;
import java.awt.Graphics2D;
/**
* 用于绘制svg图片缩放(高分屏下)
*
* @author hades
* @version 11.0
* Created by hades on 2022/5/6
*/
public class SvgPaintUtils {
public static void beforePaint(Graphics2D g2) {
if (SystemScaleUtils.isJreHiDPIEnabled()) {
g2.scale(1 / SVGIcon.SYSTEM_SCALE, 1 / SVGIcon.SYSTEM_SCALE);
}
}
public static void afterPaint(Graphics2D g2) {
if (SystemScaleUtils.isJreHiDPIEnabled()) {
g2.scale(SVGIcon.SYSTEM_SCALE, SVGIcon.SYSTEM_SCALE);
}
}
}

23
designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java

@ -85,6 +85,8 @@ import static javax.swing.JOptionPane.ERROR_MESSAGE;
* 创建组件事件
*/
public class CreateComponentAction extends UpdateAction {
private static final double MAX_WIDTH = 960.0;
private static final double MAX_HEIGHT = 540.0;
ShareUIAspect aspect;
/**
* 等待时间 500 ms.
@ -123,6 +125,11 @@ public class CreateComponentAction extends UpdateAction {
return;
}
if (isBeyondMaxSize(sharedTriple.getRight())) {
showErrMsgDialog(Toolkit.i18nText("Fine-Design_Share_Widget_Size_Error_Tip"));
return;
}
Widget widget = sharedTriple.getLeft();
try {
@ -410,4 +417,20 @@ public class CreateComponentAction extends UpdateAction {
}
return paras;
}
private boolean isBeyondMaxSize(Rectangle rec) {
double width = rec.getWidth();
double height = rec.getHeight();
return width > 0 && height > 0 && (width > MAX_WIDTH || height > MAX_HEIGHT);
}
private void showErrMsgDialog(String err) {
FineJOptionPane.showMessageDialog(
DesignerContext.getDesignerFrame(),
err,
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
ERROR_MESSAGE,
IOUtils.readIcon("/com/fr/base/images/share/Information_Icon_warning_normal_32x32.png")
);
}
}

77
designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe.share.ui.widgetfilter;
import com.fr.design.i18n.Toolkit;
import com.fr.form.share.bean.WidgetFilterInfo;
import com.fr.form.share.bean.WidgetFilterTypeInfo;
@ -16,60 +17,60 @@ public class LocalWidgetFilterCategory {
List<WidgetFilterTypeInfo> category = new ArrayList<>();
WidgetFilterTypeInfo source = new WidgetFilterTypeInfo();
source.setTitle("来源");
source.setTitle(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Source"));
source.setKey("2@source");
source.addFilterItem(new WidgetFilterInfo("本地", "1", "source"));
source.addFilterItem(new WidgetFilterInfo("商城", "2", "source"));
source.addFilterItem(new WidgetFilterInfo("全部", "0", "source"));
source.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Local"), "1", "source"));
source.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Shop"), "2", "source"));
source.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_All"), "0", "source"));
WidgetFilterTypeInfo displayDevice = new WidgetFilterTypeInfo();
displayDevice.setTitle("展示终端");
displayDevice.setTitle(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Show_Device"));
displayDevice.setKey("1@displayDevice");
displayDevice.addFilterItem(new WidgetFilterInfo("PC", "1", "displayDevice"));
displayDevice.addFilterItem(new WidgetFilterInfo("移动端", "2", "displayDevice"));
displayDevice.addFilterItem(new WidgetFilterInfo("全部", "0", "displayDevice"));
displayDevice.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_PC"), "1", "displayDevice"));
displayDevice.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Mobile"), "2", "displayDevice"));
displayDevice.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_All"), "0", "displayDevice"));
WidgetFilterTypeInfo fee = new WidgetFilterTypeInfo();
fee.setTitle("价格");
fee.setTitle(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Price"));
fee.setKey("2@fee");
fee.addFilterItem(new WidgetFilterInfo("付费", "2", "fee"));
fee.addFilterItem(new WidgetFilterInfo("免费", "1", "fee"));
fee.addFilterItem(new WidgetFilterInfo("全部", "0", "fee"));
fee.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Pay"), "2", "fee"));
fee.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Free"), "1", "fee"));
fee.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_All"), "0", "fee"));
WidgetFilterTypeInfo chart = new WidgetFilterTypeInfo();
chart.setTitle("基础元素");
chart.setTitle(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Basic_Element"));
chart.setKey("3@chart");
chart.addFilterItem(new WidgetFilterInfo("柱形图/条形图", "1", "chart"));
chart.addFilterItem(new WidgetFilterInfo("折线图", "3", "chart"));
chart.addFilterItem(new WidgetFilterInfo("组合图", "4", "chart"));
chart.addFilterItem(new WidgetFilterInfo("饼图", "2", "chart"));
chart.addFilterItem(new WidgetFilterInfo("仪表盘", "5", "chart"));
chart.addFilterItem(new WidgetFilterInfo("地图", "6", "chart"));
chart.addFilterItem(new WidgetFilterInfo("其他图表", "7", "chart"));
chart.addFilterItem(new WidgetFilterInfo("明细表", "8", "chart"));
chart.addFilterItem(new WidgetFilterInfo("基础控件", "9", "chart"));
chart.addFilterItem(new WidgetFilterInfo("全部", "0", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Bar_Chart"), "1", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Line_Chart"), "3", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Combination_Chart"), "4", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Pie_Chart"), "2", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Dashboard_Chart"), "5", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Map"), "6", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Other_Chart"), "7", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Detail_List"), "8", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Basic_Widget"), "9", "chart"));
chart.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_All"), "0", "chart"));
WidgetFilterTypeInfo report = new WidgetFilterTypeInfo();
report.setTitle("综合应用");
report.setTitle(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Comprehensive_Application"));
report.setKey("4@report");
report.addFilterItem(new WidgetFilterInfo("指标卡", "1", "report"));
report.addFilterItem(new WidgetFilterInfo("标题头", "2", "report"));
report.addFilterItem(new WidgetFilterInfo("特殊功能卡", "4", "report"));
report.addFilterItem(new WidgetFilterInfo("多维度切换", "5", "report"));
report.addFilterItem(new WidgetFilterInfo("移动目录导航", "6", "report"));
report.addFilterItem(new WidgetFilterInfo("填报", "8", "report"));
report.addFilterItem(new WidgetFilterInfo("全部", "0", "report"));
report.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Indicator_Card"), "1", "report"));
report.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Title_Head"), "2", "report"));
report.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Special_Function_Card"), "4", "report"));
report.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Multi_Dimensional_Switch"), "5", "report"));
report.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Move_Directory_Navigation"), "6", "report"));
report.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Write_Report"), "8", "report"));
report.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_All"), "0", "report"));
WidgetFilterTypeInfo style = new WidgetFilterTypeInfo();
style.setTitle("风格");
style.setTitle(Toolkit.i18nText("Fine-Design_Share_Filter_Style"));
style.setKey("5@style");
style.addFilterItem(new WidgetFilterInfo("简约清新", "1", "style"));
style.addFilterItem(new WidgetFilterInfo("商务稳重", "2", "style"));
style.addFilterItem(new WidgetFilterInfo("活泼绚丽", "3", "style"));
style.addFilterItem(new WidgetFilterInfo("酷炫科技", "4", "style"));
style.addFilterItem(new WidgetFilterInfo("其他风格", "5", "style"));
style.addFilterItem(new WidgetFilterInfo("全部", "0", "style"));
style.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Simple_Fresh"), "1", "style"));
style.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Business_Stable"), "2", "style"));
style.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Lively_And_Bright"), "3", "style"));
style.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Cool_Technology"), "4", "style"));
style.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_Other_Style"), "5", "style"));
style.addFilterItem(new WidgetFilterInfo(Toolkit.i18nText("Fine-Design_Share_Local_Filter_Item_All"), "0", "style"));
category.add(displayDevice);
category.add(source);

57
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java

@ -1,13 +1,20 @@
package com.fr.design.mainframe.alphafine;
import com.fr.base.extension.FileExtension;
import com.fr.base.svg.IconUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.DesignUtils;
import com.fr.general.CloudCenter;
import com.fr.general.IOUtils;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.swing.Icon;
/**
@ -54,6 +61,11 @@ public class AlphaFineConstants {
public static final Dimension HOT_ISSUES_JAPNEL_SIZE = new Dimension(213, 182);
/**
* 展示面板的尺寸
*/
public static final Dimension PREVIEW_SIZE = new Dimension(680, 305);
public static final Dimension CLOSE_BUTTON_SIZE = new Dimension(40, 40);
public static final Color WHITE = new Color(0xf9f9f9);
@ -131,6 +143,12 @@ public class AlphaFineConstants {
public static final String ALPHA_PREVIEW = CloudCenter.getInstance().acquireUrlByKind("af.preview");
public static final String ALPHA_CID = CloudCenter.getInstance().acquireUrlByKind("af.cid", "https://cid.fanruan.com/api/nav/alphafine");
private static final String DEFAULT_RECOMMEND = "[ { \"name\":\"快速入门指南\", \"link\":\"https://help.fanruan.com/finereport/doc-view-1335.html?source=3\" }, { \"name\":\"报表应用学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-1336.html?source=3\" }, { \"name\":\"参数应用学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4219.html?source=3\" }, { \"name\":\"填报学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4103.html?source=3\" }, { \"name\":\"API接口汇总\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4327.html?source=3\" }, { \"name\":\"文档月刊\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4613.html?source=3\" } ]";
public static final String ALPHA_HELP_RECOMMEND = CloudCenter.getInstance().acquireUrlByKind("af.recommend", DEFAULT_RECOMMEND);
public static final String JAVASCRIPT_PREFIX = "javascript:SendJava";
public static final String CHINESE_CHARACTERS = "[\\u4e00-\\u9fa5]";
@ -143,10 +161,49 @@ public class AlphaFineConstants {
public static final String BACK_ICON_NAME = "back@1x.png";
public static final Icon NO_RESULT_ICON = IOUtils.readIcon(AlphaFineConstants.IMAGE_URL + "noresult.png");
public static final Color SUSPENDED_COLOR = new Color(84, 165, 249);
public static final Color FOREGROUND_COLOR = new Color(51, 51, 52);
/**
* 后面数字代表透明度 80%
*/
public static final Color FOREGROUND_COLOR_8 = new Color(51, 51, 52, 204);
public static final Color FOREGROUND_COLOR_6 = new Color(51, 51, 52, 153);
public static final Color FOREGROUND_COLOR_5 = new Color(51, 51, 52, 128);
public static final Color BACKGROUND_COLOR = new Color(245, 245, 247);
public static final Icon BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/bulb.svg");
public static final Icon BLUE_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/blue_bulb.svg");
public static final String HOT_SEARCH = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search");
public static final Set<String> HOT_SEARCH_SET = new LinkedHashSet<>(
Arrays.asList(
Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search_TOP_ONE"),
Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search_TOP_TWO"),
Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search_TOP_THREE")
)
);
public static final ArrayList<String> CONJUNCTION = new ArrayList<String>() {{
add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Conjunction_HE"));
add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Conjunction_YU"));
add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Conjunction_DE"));
}};
public static final String LOADING = "loading";
public static final String NETWORK_ERROR = "network error";
public static final String TITLE = "AlphaFine";
public static final int DEFAULT_CLICK_COUNT = 1;
}

23
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineHelper.java

@ -2,12 +2,11 @@ package com.fr.design.mainframe.alphafine;
import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.cell.model.MoreModel;
import com.fr.design.mainframe.alphafine.cell.model.NoResultModel;
import com.fr.design.mainframe.alphafine.cell.model.RobotModel;
import com.fr.design.mainframe.alphafine.component.AlphaFineDialog;
import com.fr.design.mainframe.alphafine.component.AlphaFineFrame;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.search.manager.impl.DocumentSearchManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.HotIssuesManager;
@ -25,6 +24,7 @@ import com.fr.json.JSONFactory;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import java.awt.Frame;
import java.util.List;
/**
@ -32,7 +32,7 @@ import java.util.List;
*/
public class AlphaFineHelper {
public static final NoResultModel NO_CONNECTION_MODEL = new NoResultModel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Connection_Failed"));
private static AlphaFineDialog alphaFineDialog;
private static AlphaFineFrame alphaFineDialog;
private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com";
private AlphaFineHelper() {
@ -62,17 +62,30 @@ public class AlphaFineHelper {
return;
}
if (alphaFineDialog == null) {
alphaFineDialog = new AlphaFineDialog(DesignerContext.getDesignerFrame(), forceOpen);
alphaFineDialog = new AlphaFineFrame();
alphaFineDialog.setVisible(true);
final AlphaFineConfigManager manager = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager();
manager.setNeedRemind(false);
} else {
alphaFineDialog.setVisible(!alphaFineDialog.isVisible());
alphaFineDialog.setVisible(true);
// check 如果最小化 点击悬浮按钮后 恢复
if ((alphaFineDialog.getExtendedState() & Frame.ICONIFIED) != 0) {
// 从最小化恢复
alphaFineDialog.setExtendedState(Frame.NORMAL);
}
alphaFineDialog.toFront();
}
}
public static void resetAlphaFineDialog() {
alphaFineDialog = null;
}
public static AlphaFineFrame getAlphaFineDialog() {
return alphaFineDialog;
}
/**
* 获取文件名上级目录

77
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java

@ -0,0 +1,77 @@
package com.fr.design.mainframe.alphafine;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager;
import com.fr.stable.StringUtils;
import java.util.Set;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/20
*/
public class AlphaFineUtil {
public static String highLightModelName(String modelName, String[] strings) {
if (strings == null) {
return modelName;
}
for (String string : strings) {
String primaryStr = getReplacedString(modelName, string);
if (StringUtils.isNotEmpty(primaryStr)) {
modelName = modelName.replaceAll("(?i)" + primaryStr, "|<font color=" + AlphaFineConstants.HIGH_LIGHT_COLOR + ">" + primaryStr + "</font>|");
}
}
modelName = "<html><head><style> .style{" +
"overflow: hidden;" +
"text-overflow: ellipsis;" +
"white-space: nowrap;}" +
"</style></head><body class=\"style\">" + modelName.replaceAll("\\|", StringUtils.EMPTY) + "</body></HTML>";
return modelName;
}
private static String getReplacedString(String modelName, String string) {
// 如果是直接包含了高亮字符 返回
if (StringUtils.contains(modelName, string)) {
return string;
}
//需要考虑modelName有空格的情况
//比如现在是work boo k 搜索词是workb,应该要替换的部分是work b
//先去掉已经匹配替换过的部分,因为考虑到分词的情况,可能会进行多次替换
final String regex = "\\|<font.*?</font>\\|";
modelName = modelName.replaceAll(regex, StringUtils.EMPTY);
//再去掉空格进行匹配
String noBlackName = modelName.replaceAll(StringUtils.BLANK, StringUtils.EMPTY).toLowerCase();
int index = noBlackName.indexOf(string.toLowerCase());
if (index == -1) {
return StringUtils.EMPTY;
}
StringBuilder result = new StringBuilder();
int count = 0;
while (count < string.length()) {
char pos = modelName.charAt(index++);
result.append(pos);
count += pos == ' ' ? 0 : 1;
}
return result.toString();
}
public static String escapeExprSpecialWord(String keyword) {
if (StringUtils.isNotBlank(keyword)) {
String[] fbsArr = { "\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|" };
for (String key : fbsArr) {
if (keyword.contains(key)) {
keyword = keyword.replace(key, "\\" + key);
}
}
}
return keyword;
}
public static boolean unread() {
Set<Long> readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet();
Set<Long> idSet = ProductNewsSearchManager.getInstance().getIdSet();
return !idSet.isEmpty() && !readSet.containsAll(idSet);
}
}

50
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java

@ -1,15 +1,49 @@
package com.fr.design.mainframe.alphafine;
import com.fr.stable.StringUtils;
/**
* Created by XiaXiang on 2017/4/27.
*/
public enum CellType {
RECOMMEND(0), ACTION(1), DOCUMENT(2), FILE(3), PLUGIN(4), REUSE(5), NO_RESULT(6), MORE(7), RECOMMEND_ROBOT(8), BOTTOM(9), ROBOT(10);
RECOMMEND(0),
ACTION(1, "action", "actionResult", false),
DOCUMENT(2, "document", "documentResult", true),
FILE(3, "file", "fileResult", false),
PLUGIN(4, "plugin", "pluginResult", true),
REUSE(5),
NO_RESULT(6, "noResult", StringUtils.EMPTY, false),
MORE(7),
RECOMMEND_ROBOT(8),
BOTTOM(9),
ROBOT(10),
PRODUCT_NEWS(11, "productNews", "productNewsResult", true);
private int typeValue;
CellType(int type) {
/**
* 标志位 索引无搜索结果面板
*
* 空字符表示不涉及索引该项
*/
private String flagStr4None;
/**
* 标志位 索引有搜索结果面板
*/
private String flagStr4Result;
private boolean needNetWork = true;
CellType(int type, String flagStr4None, String flagStr4Result, boolean needNetWork) {
this.typeValue = type;
this.flagStr4None = flagStr4None;
this.flagStr4Result = flagStr4Result;
this.needNetWork = needNetWork;
}
CellType(int type) {
this(type, StringUtils.EMPTY, StringUtils.EMPTY, true);
}
public static CellType parse(int typeValue) {
@ -29,5 +63,17 @@ public enum CellType {
public void setTypeValue(int typeValue) {
this.typeValue = typeValue;
}
public String getFlagStr4None() {
return flagStr4None;
}
public String getFlagStr4Result() {
return flagStr4Result;
}
public boolean isNeedNetWork() {
return needNetWork;
}
}

6
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java

@ -435,7 +435,7 @@ public class AlphaFineDialog extends UIDialog {
*/
private void removeLeftPane() {
if (searchListModel.isEmpty() && defaultPane == null) {
defaultPane = new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result"), AlphaFineConstants.IMAGE_URL + "no_result.png");
defaultPane = new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result"), AlphaFineConstants.NO_RESULT_ICON);
searchResultPane.remove(leftSearchResultPane);
searchResultPane.add(defaultPane, BorderLayout.WEST);
refreshContainer();
@ -636,7 +636,7 @@ public class AlphaFineDialog extends UIDialog {
bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportWorkBookAsImageData(fileName);
} catch (Exception ignored) {
// 兼容下老版本
bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName);
bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName);
}
return TemplateExportOperator.byteDataToImage(bytes);
}
@ -661,7 +661,7 @@ public class AlphaFineDialog extends UIDialog {
break;
case ACTION:
rightSearchResultPane.removeAll();
rightSearchResultPane.add(new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result"), AlphaFineConstants.IMAGE_URL + "noresult.png"));
rightSearchResultPane.add(new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result"), AlphaFineConstants.NO_RESULT_ICON));
validate();
repaint();
break;

832
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java

@ -0,0 +1,832 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.base.svg.IconUtils;
import com.fr.base.svg.SVGLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager;
import com.fr.design.actions.help.alphafine.AlphaFineShortCutUtil;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.borders.UITextFieldBorder;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.model.ProductNews;
import com.fr.design.mainframe.alphafine.preview.DefaultProductNewsPane;
import com.fr.design.mainframe.alphafine.preview.HelpDocumentNoResultPane;
import com.fr.design.mainframe.alphafine.preview.LoadingRightSearchResultPane;
import com.fr.design.mainframe.alphafine.preview.NetWorkFailedPane;
import com.fr.design.mainframe.alphafine.preview.NoResultPane;
import com.fr.design.mainframe.alphafine.preview.NoResultWithLinkPane;
import com.fr.design.mainframe.alphafine.preview.SearchLoadingPane;
import com.fr.design.mainframe.alphafine.preview.SimpleRightSearchResultPane;
import com.fr.design.mainframe.alphafine.question.QuestionWindow;
import com.fr.design.mainframe.alphafine.search.ProductNewsSearchWorkerManager;
import com.fr.design.mainframe.alphafine.search.SearchTextBean;
import com.fr.design.mainframe.alphafine.search.SearchWorkerManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.ActionSearchManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.DocumentSearchManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.FileSearchManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.PluginSearchManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager;
import com.fr.design.mainframe.alphafine.search.manager.impl.SegmentationManager;
import com.fr.design.utils.DesignUtils;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/04/06
*/
public class AlphaFineFrame extends JFrame {
private static final String ADVANCED_SEARCH_MARK = "k:";
private static final String ACTION_MARK_SHORT = "k:1 ";
private static final String ACTION_MARK = "k:setting ";
private static final String DOCUMENT_MARK_SHORT = "k:2 ";
private static final String DOCUMENT_MARK = "k:help ";
private static final String FILE_MARK_SHORT = "k:3 ";
private static final String FILE_MARK = "k:reportlets ";
private static final String CPT_MARK = "k:cpt ";
private static final String FRM_MARK = "k:frm ";
private static final String DS_MARK = "k:ds ";
private static final String DS_NAME = "dsname=\"";
private static final String PLUGIN_MARK_SHORT = "k:4 ";
private static final String PLUGIN_MARK = "k:shop ";
private static final int TIMER_DELAY = 300;
private static final String PLACE_HOLDER = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine");
private static final String SETTING = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set");
private static final String NO_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result");
private static final String SKILLS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Skills");
private static final String SEARCH_TERM = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Search_Term");
private static final String SEARCH = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Search");
private static final String GO_FORUM = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Go_Forum");
private static final String TEMPLATES = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Templates");
public static final String PRODUCT_NEWS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_News");
private static final String HELP = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help");
private static final String PLUGIN = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon");
private static final String ONE_CLICK_READ = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_One_Click_Read");
private static final String NO_SEARCH_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result");
private static final String PRODUCT_DYNAMICS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_Dynamics");
private static final Image SEARCH_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/search.svg");
private static final Color BORDER_COLOR = new Color(232, 232, 233);
private final CardLayout cardLayout = new CardLayout();
private final JPanel resultPane = new JPanel(cardLayout);
private String storeText;
private String[] segmentationResult;
private UILabel useTipLabel;
private UILabel tipIconLabel;
private AlphaFineTextField searchTextField;
private AlphaFineList searchResultList;
private SearchLoadingPane searchLoadingPane;
private JPanel searchTextFieldWrapperPane;
private UILabel clearLabel;
private CellType selectedType;
private String beforeSearchStr = StringUtils.EMPTY;
private SearchWorkerManager settingSearchWorkerManager;
private SearchWorkerManager fileSearchWorkerManager;
private SearchWorkerManager documentWorkerManager;
private SearchWorkerManager pluginSearchWorkerManager;
private SearchWorkerManager currentSearchWorkerManager;
private ProductNewsSearchWorkerManager productNewsSearchWorkerManager;
public AlphaFineFrame() {
this.setTitle(AlphaFineConstants.TITLE);
setUndecorated(true);
setSize(AlphaFineConstants.FIELD_SIZE);
initComponents();
centerWindow(this);
initSearchManager();
}
private void initSearchManager() {
this.productNewsSearchWorkerManager = new ProductNewsSearchWorkerManager(
CellType.PRODUCT_NEWS,
searchTextBean -> {
return ProductNewsSearchManager.getInstance().getSearchResult(searchTextBean.getSegmentation());
},
this
);
this.settingSearchWorkerManager = new SearchWorkerManager(
CellType.ACTION,
searchTextBean -> ActionSearchManager.getInstance().getSearchResult(searchTextBean),
this,
new SimpleRightSearchResultPane(new NoResultPane(NO_RESULT, AlphaFineConstants.NO_RESULT_ICON))
);
fileSearchWorkerManager = new SearchWorkerManager(
CellType.FILE,
searchTextBean -> FileSearchManager.getInstance().getSearchResult(searchTextBean),
this,
new LoadingRightSearchResultPane()
);
documentWorkerManager = new SearchWorkerManager(
CellType.DOCUMENT,
searchTextBean -> DocumentSearchManager.getInstance().getSearchResult(searchTextBean),
this,
new SimpleRightSearchResultPane(new JPanel())
);
pluginSearchWorkerManager = new SearchWorkerManager(
CellType.PLUGIN,
searchTextBean -> PluginSearchManager.getInstance().getSearchResult(searchTextBean),
this,
new LoadingRightSearchResultPane()
);
}
/**
* 初始化全部组件
*/
private void initComponents() {
add(createTopPane(), BorderLayout.NORTH);
initSearchTextField();
add(createSearchPane(), BorderLayout.CENTER);
add(createShowPane(), BorderLayout.SOUTH);
this.getContentPane().setBackground(Color.WHITE);
this.setIconImage(SEARCH_IMAGE);
this.setSize(AlphaFineConstants.FULL_SIZE);
}
private JPanel createTopPane() {
JPanel topPane = new JPanel(new BorderLayout());
topPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
topPane.setBackground(Color.WHITE);
JPanel topLeftPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
topLeftPane.setBackground(Color.WHITE);
UILabel alphaFineLabel = new UILabel(AlphaFineConstants.TITLE);
alphaFineLabel.setFont(new Font("Arial Black", Font.PLAIN, 20));
alphaFineLabel.setForeground(UIConstants.FLESH_BLUE);
topLeftPane.add(alphaFineLabel);
topPane.add(topLeftPane, BorderLayout.WEST);
JPanel topRightPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
topRightPane.setBackground(Color.WHITE);
JPanel tipPane = new JPanel(new BorderLayout());
tipPane.setBackground(Color.WHITE);
String toolTip = AlphaFineShortCutUtil.getDisplayShortCut(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Short_Cut", DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getShortcuts()));
tipIconLabel = new UILabel(AlphaFineConstants.BULB_ICON);
tipIconLabel.addMouseListener(tipMouseListener);
tipIconLabel.setToolTipText(toolTip);
useTipLabel = new UILabel(SKILLS);
useTipLabel.addMouseListener(tipMouseListener);
useTipLabel.setToolTipText(toolTip);
useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
tipPane.add(tipIconLabel, BorderLayout.WEST);
tipPane.add(useTipLabel, BorderLayout.CENTER);
topRightPane.add(tipPane);
UIButton minimizeButton = createButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/minimize.svg"));
minimizeButton.addActionListener(e -> AlphaFineFrame.this.setExtendedState(JFrame.ICONIFIED));
topRightPane.add(minimizeButton);
UIButton closeButton = createButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/close.svg"));
closeButton.addActionListener(e -> AlphaFineFrame.this.dispose());
topRightPane.add(closeButton);
topPane.add(topRightPane, BorderLayout.EAST);
return topPane;
}
private MouseAdapter tipMouseListener = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
useTipLabel.setForeground(UIConstants.FLESH_BLUE);
tipIconLabel.setIcon(AlphaFineConstants.BLUE_BULB_ICON);
}
@Override
public void mouseExited(MouseEvent e) {
useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON);
}
};
private JPanel createSearchPane() {
JPanel searchPane = new JPanel(new BorderLayout());
searchPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20));
searchTextFieldWrapperPane = new JPanel(new BorderLayout()) {
@Override
protected void paintBorder(Graphics g) {
g.setColor(BORDER_COLOR);
g.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 5, 5);
}
};
searchTextFieldWrapperPane.setBorder(new UITextFieldBorder(new Insets(2, 3, 2, 3)));
searchTextFieldWrapperPane.setBackground(Color.WHITE);
searchTextFieldWrapperPane.add(searchTextField, BorderLayout.CENTER);
clearLabel = new UILabel(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/clear.svg"));
clearLabel.setVisible(false);
clearLabel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
searchTextField.setText(StringUtils.EMPTY);
beforeSearchStr = StringUtils.EMPTY;
clearLabel.setVisible(false);
}
});
searchTextFieldWrapperPane.add(clearLabel, BorderLayout.EAST);
searchPane.add(searchTextFieldWrapperPane, BorderLayout.CENTER);
JButton searchButton = new JButton(SEARCH) {
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(UIConstants.FLESH_BLUE);
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 4, 4);
super.paintComponent(g2d);
}
};
searchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fireSearch();
}
});
searchButton.setPreferredSize(new Dimension(70, 60));
searchButton.setForeground(Color.WHITE);
searchButton.setBorderPainted(false);
searchButton.setContentAreaFilled(false);
searchPane.add(searchButton, BorderLayout.EAST);
searchPane.setBackground(Color.WHITE);
return searchPane;
}
private JPanel createShowPane() {
JPanel showPane = new JPanel(new BorderLayout());
resultPane.add(new DefaultProductNewsPane(), CellType.PRODUCT_NEWS.getFlagStr4None());
resultPane.add(new NoResultWithLinkPane(GO_FORUM, AlphaFineConstants.NO_RESULT_ICON), CellType.NO_RESULT.getFlagStr4None());
resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.ACTION.getFlagStr4None());
resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.FILE.getFlagStr4None());
resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.PLUGIN.getFlagStr4None());
resultPane.add(new HelpDocumentNoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.DOCUMENT.getFlagStr4None());
resultPane.add(new NetWorkFailedPane(this::reSearch), AlphaFineConstants.NETWORK_ERROR);
JPanel labelPane = new JPanel(new BorderLayout());
labelPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20));
labelPane.setBackground(Color.WHITE);
JPanel labelContentPane = new JPanel(new BorderLayout());
UILabel tabLabel = new UILabel(PRODUCT_DYNAMICS);
tabLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
tabLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
tabLabel.setPreferredSize(new Dimension(100, 30));
JPanel westPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
westPane.add(tabLabel);
labelContentPane.add(westPane, BorderLayout.WEST);
JPanel eastPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
UILabel readLabel = new UILabel(ONE_CLICK_READ);
readLabel.setHorizontalAlignment(SwingConstants.RIGHT);
readLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));;
readLabel.setPreferredSize(new Dimension(100, 30));
readLabel.setForeground(UIConstants.FLESH_BLUE);
readLabel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
fireOneClickRead();
showPane.repaint();
}
});
eastPane.add(readLabel);
labelContentPane.add(eastPane, BorderLayout.EAST);
labelContentPane.setBackground(new Color(245, 245, 247));
labelPane.add(labelContentPane);
labelPane.setPreferredSize(new Dimension(AlphaFineConstants.FULL_SIZE.width, 30));
JPanel tabPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10));
tabPane.setBackground(Color.WHITE);
List<SelectedLabel> selectedLabelList = createSelectedLabelList();
selectedType = selectedLabelList.get(0).getCellType();
// 第一个tab 非产品动态
if (selectedType != CellType.PRODUCT_NEWS) {
tabLabel.setText(selectedLabelList.get(0).getText());
readLabel.setVisible(false);
}
for (SelectedLabel selectedLabel : selectedLabelList) {
selectedLabel.addMouseListener(createMouseListener(selectedLabelList, selectedLabel, tabPane, tabLabel, readLabel));
tabPane.add(selectedLabel);
}
showPane.add(tabPane, BorderLayout.NORTH);
showPane.add(labelPane, BorderLayout.CENTER);
showPane.add(resultPane, BorderLayout.SOUTH);
return showPane;
}
private MouseAdapter createMouseListener(List<SelectedLabel> selectedLabelList, SelectedLabel selectedLabel,
JPanel tabPane, UILabel tabLabel, UILabel readLabel) {
return new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
for (SelectedLabel label : selectedLabelList) {
label.setSelected(false);
label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8);
}
selectedLabel.setSelected(true);
// 处理产品动态 tab与下方文字展示不一致
if (ComparatorUtils.equals(selectedLabel.getText().trim(), PRODUCT_NEWS)) {
tabLabel.setText(PRODUCT_DYNAMICS);
} else {
tabLabel.setText(selectedLabel.getText());
}
readLabel.setVisible(false);
tabPane.repaint();
switch (selectedLabel.getCellType()) {
case PRODUCT_NEWS:
readLabel.setVisible(true);
switchType(CellType.PRODUCT_NEWS);
break;
case ACTION:
currentSearchWorkerManager = settingSearchWorkerManager;
switchType(CellType.ACTION);
break;
case FILE:
currentSearchWorkerManager = fileSearchWorkerManager;
switchType(CellType.FILE);
break;
case DOCUMENT:
currentSearchWorkerManager = documentWorkerManager;
switchType(CellType.DOCUMENT);
break;
case PLUGIN:
currentSearchWorkerManager = pluginSearchWorkerManager;
switchType(CellType.PLUGIN);
break;
}
if (currentSearchWorkerManager != null) {
AlphaFineList alphaFineList = currentSearchWorkerManager.getSearchResultList();
if (alphaFineList != null) {
alphaFineList.setSelectedIndex(0);
}
}
}
private Color defaultColor;
@Override
public void mouseEntered(MouseEvent e) {
defaultColor = selectedLabel.getForeground();
selectedLabel.setForeground(AlphaFineConstants.SUSPENDED_COLOR);
}
@Override
public void mouseExited(MouseEvent e) {
selectedLabel.setForeground(defaultColor);
}
};
}
private List<SelectedLabel> createSelectedLabelList() {
List<SelectedLabel> selectedLabelList = new ArrayList<>();
AlphaFineConfigManager alphaFineConfigManager = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager();
if (alphaFineConfigManager.isProductDynamics()) {
selectedLabelList.add(new SelectedLabel(PRODUCT_NEWS, CellType.PRODUCT_NEWS, true));
}
if (alphaFineConfigManager.isContainAction()) {
selectedLabelList.add(new SelectedLabel(SETTING, CellType.ACTION));
}
if (alphaFineConfigManager.isContainFileContent() || alphaFineConfigManager.isContainTemplate()) {
selectedLabelList.add(new SelectedLabel(TEMPLATES, CellType.FILE));
}
if (alphaFineConfigManager.isContainDocument()) {
selectedLabelList.add(new SelectedLabel(HELP, CellType.DOCUMENT));
}
if (alphaFineConfigManager.isContainPlugin()) {
selectedLabelList.add(new SelectedLabel(PLUGIN, CellType.PLUGIN));
}
return selectedLabelList;
}
private void fireOneClickRead() {
List<ProductNews> productNewsList = ProductNewsSearchManager.getInstance().getCachedProductNewsList();
Set<Long> readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet();
for (ProductNews productNews : productNewsList) {
readSet.add(productNews.getId());
}
}
private void switchType(CellType cellType) {
this.selectedType = cellType;
if (StringUtils.isEmpty(searchTextField.getText())) {
cardLayout.show(resultPane, cellType.getFlagStr4None());
} else {
// 当前搜索未结束 不切换loading
if (!checkSearchLoading()) {
return;
}
// 所有都搜索都结束 移除loading
if (isAllSearchOver()) {
resultPane.remove(searchLoadingPane);
}
// 网络异常
if (checkNetworkError()) {
return;
}
cardLayout.show(resultPane, cellType.getFlagStr4Result());
checkSearchResult();
}
}
private boolean checkNetworkError() {
boolean networkError;
if (selectedType == CellType.PRODUCT_NEWS) {
networkError = productNewsSearchWorkerManager.isNetWorkError();
} else {
networkError = currentSearchWorkerManager.isNetWorkError();
}
cardLayout.show(resultPane, AlphaFineConstants.NETWORK_ERROR);
return networkError;
}
private boolean checkSearchLoading() {
boolean searchOver;
if (selectedType == CellType.PRODUCT_NEWS) {
searchOver = productNewsSearchWorkerManager.isSearchOver();
} else {
searchOver = currentSearchWorkerManager.isSearchOver();
}
cardLayout.show(resultPane, AlphaFineConstants.LOADING);
return searchOver;
}
private boolean isAllSearchOver() {
return productNewsSearchWorkerManager.isSearchOver()
&& pluginSearchWorkerManager.isSearchOver()
&& fileSearchWorkerManager.isSearchOver()
&& settingSearchWorkerManager.isSearchOver()
&& documentWorkerManager.isSearchOver();
}
private void checkSearchResult() {
if (currentSearchWorkerManager == null) {
return;
}
searchResultList = currentSearchWorkerManager.getSearchResultList();
if (searchResultList != null) {
searchResultList.requestFocus();
}
boolean hasSearchResult = true;
if (selectedType == CellType.PRODUCT_NEWS) {
hasSearchResult = productNewsSearchWorkerManager.hasSearchResult();
} else {
hasSearchResult = currentSearchWorkerManager.hasSearchResult();
}
if (!hasSearchResult) {
cardLayout.show(resultPane, CellType.NO_RESULT.getFlagStr4None());
}
}
private void initSearchTextField() {
searchTextField = new AlphaFineTextField(PLACE_HOLDER);
initTextFieldListener();
searchTextField.setFont(DesignUtils.getDefaultGUIFont().applySize(14));
searchTextField.setBackground(Color.WHITE);
searchTextField.setPreferredSize(new Dimension(300, 60));
searchTextField.setBorder(null);
}
private void initTextFieldListener() {
searchTextField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
// 搜索提示框
if (StringUtils.isNotEmpty(searchTextField.getText())) {
clearLabel.setVisible(true);
SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane);
} else {
beforeSearchStr = StringUtils.EMPTY;
}
AlphaFineToolTipList alphaFineToolTipList = SearchTooltipPopup.getInstance().getAlphaFineToolTipList();
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
if (!alphaFineToolTipList.isSelectionEmpty()) {
fireSearch(alphaFineToolTipList.getSelectedValue());
return;
}
fireSearch();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
if (alphaFineToolTipList.getSelectedIndex() == alphaFineToolTipList.getModel().getSize() - 1) {
alphaFineToolTipList.setSelectedIndex(0);
}
alphaFineToolTipList.setSelectedIndex(alphaFineToolTipList.getSelectedIndex() + 1);
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
alphaFineToolTipList.setSelectedIndex(alphaFineToolTipList.getSelectedIndex() - 1);
}
}
});
searchTextField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
if (StringUtils.isNotEmpty(searchTextField.getText())) {
SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane);
}
}
@Override
public void focusLost(FocusEvent e) {
if (e.getOppositeComponent() != SearchTooltipPopup.getInstance().getAlphaFineToolTipList()) {
SearchTooltipPopup.getInstance().hide();
}
}
});
startSearchTextFieldTimer();
}
private void startSearchTextFieldTimer() {
Timer timer = new Timer(TIMER_DELAY, e -> {
// 坑 isShowing返回false 即使textField有内容 getText返回的也是空
if (searchTextField.isShowing() && StringUtils.isEmpty(searchTextField.getText())) {
SearchTooltipPopup.getInstance().hide();
clearLabel.setVisible(false);
switchType(selectedType);
beforeSearchStr = StringUtils.EMPTY;
} else if (searchTextField.hasFocus()) {
clearLabel.setVisible(true);
SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane);
}
});
timer.start();
}
public void fireSearch(String text) {
searchTextField.setText(text);
fireSearch();
}
private void fireSearch() {
// 焦点转移
AlphaFineFrame.this.requestFocus();
if (ComparatorUtils.equals(beforeSearchStr, searchTextField.getText())) {
return;
}
if (StringUtils.isEmpty(searchTextField.getText())) {
beforeSearchStr = StringUtils.EMPTY;
return;
}
if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isNeedSegmentationCheckbox()) {
//是高级搜索
if (searchTextField.getText().toLowerCase().startsWith(ADVANCED_SEARCH_MARK)) {
segmentationResult = SegmentationManager.getInstance().startSegmentation(getStoreText(searchTextField.getText().toLowerCase()));
}
//是普通搜索
else {
segmentationResult = SegmentationManager.getInstance().startSegmentation(searchTextField.getText().toLowerCase());
}
} else {
if (StringUtils.isEmpty(getRealSearchText(searchTextField.getText()))) {
segmentationResult = null;
} else {
segmentationResult = new String[]{getRealSearchText(searchTextField.getText())};
}
}
DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getHistorySearch().push(searchTextField.getText());
doSearch(searchTextField.getText().toLowerCase());
beforeSearchStr = searchTextField.getText();
SearchTooltipPopup.getInstance().hide();
}
private void dealWithSearchResult() {
final AlphaCellModel model = searchResultList.getSelectedValue();
if (model != null) {
model.doAction();
}
}
public void showResult(String flag) {
cardLayout.show(resultPane, flag);
}
public void addResult(JPanel panel, String flag) {
resultPane.add(panel, flag);
}
public void removeSearchResultPane(JPanel panel) {
resultPane.remove(panel);
}
private void doSearch(String text) {
initSearchLoadingPane();
SearchTextBean searchTextBean = generateSearchTextBean(text);
this.productNewsSearchWorkerManager.doSearch(searchTextBean);
this.settingSearchWorkerManager.doSearch(searchTextBean);
this.fileSearchWorkerManager.doSearch(searchTextBean);
this.documentWorkerManager.doSearch(searchTextBean);
this.pluginSearchWorkerManager.doSearch(searchTextBean);
}
private SearchTextBean generateSearchTextBean(String searchText) {
if (searchText.startsWith(ACTION_MARK_SHORT) || searchText.startsWith(ACTION_MARK)
|| searchText.startsWith(DOCUMENT_MARK_SHORT) || searchText.startsWith(DOCUMENT_MARK)) {
return new SearchTextBean(StringUtils.EMPTY, new String[]{getStoreText(searchText)});
} else if (searchText.startsWith(FILE_MARK_SHORT) || searchText.startsWith(FILE_MARK)
|| searchText.startsWith(CPT_MARK) || searchText.startsWith(FRM_MARK)
|| searchText.startsWith(PLUGIN_MARK_SHORT) || searchText.startsWith(PLUGIN_MARK)) {
return new SearchTextBean(getStoreText(searchText), new String[]{getStoreText(searchText)});
} else if (searchText.startsWith(DS_MARK)) {
return new SearchTextBean(getStoreText(searchText), new String[]{DS_NAME + getStoreText(searchText)});
} else {
return new SearchTextBean(searchText, segmentationResult == null ? new String[]{} : segmentationResult);
}
}
/**
* 仅搜索依赖网络的搜索项
*
*/
private void reSearch() {
String text = this.searchTextField.getText().toLowerCase();
if (StringUtils.isEmpty(text)) {
return;
}
searchLoadingPane = new SearchLoadingPane();
SearchTextBean searchTextBean = new SearchTextBean(text, segmentationResult);
this.productNewsSearchWorkerManager.doSearch(searchTextBean);
this.documentWorkerManager.doSearch(searchTextBean);
this.pluginSearchWorkerManager.doSearch(searchTextBean);
}
private void initSearchLoadingPane() {
if (searchLoadingPane == null) {
searchLoadingPane = new SearchLoadingPane();
}
resultPane.add(searchLoadingPane, AlphaFineConstants.LOADING);
cardLayout.show(resultPane, AlphaFineConstants.LOADING);
}
public String getSearchText() {
return searchTextField.getText();
}
public CellType getSelectedType() {
return selectedType;
}
public void setStoreText(String storeText) {
this.storeText = storeText;
}
/**
* 截取字符串中关键词
*
* @param searchText
* @return
*/
private String getStoreText(String searchText) {
//这里也需要先做一个去除不需要空格的处理
setStoreText((searchText.substring(searchText.indexOf(StringUtils.BLANK) + 1)).replaceAll(StringUtils.BLANK, StringUtils.EMPTY));
return storeText;
}
/**
* 去除特殊字符空格等
*/
private String getRealSearchText(String searchText) {
searchText = searchText.toLowerCase();
Pattern p = Pattern.compile(AlphaFineConstants.SPECIAL_CHARACTER_REGEX);
Matcher m = p.matcher(searchText);
searchText = m.replaceAll(StringUtils.EMPTY).trim().replaceAll(StringUtils.BLANK, StringUtils.EMPTY);
if (searchText.length() == 0) {
return null;
}
return searchText;
}
private UIButton createButton(Icon icon) {
UIButton button = new UIButton() {
@Override
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, getSize().width, getSize().height);
super.paintComponent(g);
}
};
button.setPreferredSize(new Dimension(20, 20));
button.setIcon(icon);
button.set4ToolbarButton();
button.setBorderPainted(false);
button.setRolloverEnabled(false);
return button;
}
/**
* 设置面板位置
*
* @param win
*/
private void centerWindow(Window win) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension winSize = win.getSize();
if (winSize.height > screenSize.height) {
winSize.height = screenSize.height;
}
if (winSize.width > screenSize.width) {
winSize.width = screenSize.width;
}
//这里设置位置:水平居中,竖直偏上
win.setLocation((screenSize.width - winSize.width) / 2, (screenSize.height - winSize.height) / AlphaFineConstants.SHOW_SIZE);
}
@Override
public void setVisible(boolean b) {
super.setVisible(b);
QuestionWindow.getInstance().setVisible(!b);
if (!b) {
AlphaFineHelper.resetAlphaFineDialog();
}
}
@Override
public void dispose() {
super.dispose();
AlphaFineHelper.resetAlphaFineDialog();
QuestionWindow.getInstance().setVisible(true);
}
}

84
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java

@ -0,0 +1,84 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.cell.model.DocumentModel;
import com.fr.design.mainframe.alphafine.preview.ResultShowPane;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JList;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/18
*/
public class AlphaFineList extends JList<AlphaCellModel> {
private ResultShowPane resultShowPane;
public AlphaFineList() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
AlphaCellModel selectedValue = getSelectedValue();
if (e.getClickCount() == AlphaFineConstants.DEFAULT_CLICK_COUNT && selectedValue.hasAction()) {
// 点击搜索结果 主页面移动到后面
if (!(selectedValue instanceof DocumentModel)) {
// 帮助文档不跳转
AlphaFineHelper.getAlphaFineDialog().toBack();
}
dealWithSearchResult();
}
}
});
addListSelectionListener(e -> {
if (!e.getValueIsAdjusting() && getSelectedValue() != null) {
if (resultShowPane != null) {
resultShowPane.showResult(getSelectedValue());
}
}
});
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
AlphaCellModel selectedValue = getSelectedValue();
if (selectedValue.hasAction() && !(selectedValue instanceof DocumentModel)) {
AlphaFineHelper.getAlphaFineDialog().toBack();
}
dealWithSearchResult();
}
}
});
}
public void setResultShowPane(ResultShowPane resultShowPane) {
this.resultShowPane = resultShowPane;
}
@Override
public void setSelectedIndex(int index) {
super.setSelectedIndex(index);
AlphaCellModel alphaCellModel = getSelectedValue();
if (resultShowPane != null && alphaCellModel != null) {
resultShowPane.showResult(getSelectedValue());
}
ensureIndexIsVisible(getSelectedIndex());
}
private void dealWithSearchResult() {
final AlphaCellModel model = this.getSelectedValue();
if (model != null) {
model.doAction();
}
}
}

2
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFinePane.java

@ -31,7 +31,7 @@ public class AlphaFinePane extends BasicPane {
setLayout(new BorderLayout());
UIButton refreshButton = new UIButton();
refreshButton.setIcon(IOUtils.readIcon(("/com/fr/design/mainframe/alphafine/images/smallsearch.png")));
refreshButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine"));
refreshButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Learn_More_About"));
refreshButton.set4ToolbarButton();
refreshButton.setRolloverEnabled(false);
this.add(refreshButton);

19
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineTextField.java

@ -1,8 +1,7 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.report.web.button.Image;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
@ -13,9 +12,10 @@ import java.awt.RenderingHints;
*/
public class AlphaFineTextField extends UITextField {
private static final int PLACE_HOLDER_GAP = 3;
private String placeHolder;
private Image image;
public AlphaFineTextField(String placeHolder) {
this.placeHolder = placeHolder;
@ -36,16 +36,13 @@ public class AlphaFineTextField extends UITextField {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(super.getDisabledTextColor());
g2.drawString(placeHolder, getInsets().left, g.getFontMetrics().getMaxAscent() + getInsets().top + 15);
g2.setColor(AlphaFineConstants.FOREGROUND_COLOR_5);
g2.drawString(placeHolder, getInsets().left, g.getFontMetrics().getMaxAscent() + getInsets().top + PLACE_HOLDER_GAP);
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
@Override
protected void paintBorder(Graphics g) {
// do nothing
}
public String getPlaceHolder() {

68
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipContentCellRender.java

@ -0,0 +1,68 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.base.svg.IconUtils;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineUtil;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public class AlphaFineToolTipContentCellRender implements ListCellRenderer<String> {
private static final Color SELECTED_COLOR = new Color(65, 155, 249, 26);
private static final Icon HOT_SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/hot_search.svg");
private static final Icon SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/search.svg");
private static final Icon HISTORY_SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/history_search.svg");
@Override
public Component getListCellRendererComponent(JList<? extends String> list, String value, int index,
boolean isSelected, boolean cellHasFocus) {
if (StringUtils.isEmpty(value)) {
return new LineCellRender().getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(null);
UILabel iconLabel = new UILabel();
iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0));
iconLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8);
iconLabel.setText(value);
if (ComparatorUtils.equals(value, AlphaFineConstants.HOT_SEARCH)) {
iconLabel.setIcon(HOT_SEARCH_ICON);
} else if (AlphaFineConstants.HOT_SEARCH_SET.contains(value)) {
iconLabel.setIcon(SEARCH_ICON);
} else {
iconLabel.setIcon(HISTORY_SEARCH_ICON);
}
if (isSelected && !ComparatorUtils.equals(value, AlphaFineConstants.HOT_SEARCH)) {
iconLabel.setText(AlphaFineUtil.highLightModelName(value, new String[]{value}));
panel.setBackground(SELECTED_COLOR);
}
panel.add(iconLabel, BorderLayout.WEST);
panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
panel.setPreferredSize(new Dimension(640, 32));
return panel;
}
}

42
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipList.java

@ -0,0 +1,42 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.general.ComparatorUtils;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JList;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public class AlphaFineToolTipList extends JList<String> {
public AlphaFineToolTipList() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
AlphaFineHelper.getAlphaFineDialog().fireSearch(getSelectedValue());
}
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
if (ComparatorUtils.equals(getSelectedValue(), AlphaFineConstants.HOT_SEARCH)) {
return;
}
AlphaFineHelper.getAlphaFineDialog().fireSearch(getSelectedValue());
}
}
});
}
}

62
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaSearchTooltipPane.java

@ -0,0 +1,62 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.DesignerEnvManager;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import java.awt.Color;
import java.awt.Dimension;
import java.util.Stack;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public class AlphaSearchTooltipPane extends JPanel {
private AlphaFineToolTipList alphaFineToolTipList;
public AlphaSearchTooltipPane() {
alphaFineToolTipList = new AlphaFineToolTipList();
alphaFineToolTipList.setCellRenderer(new AlphaFineToolTipContentCellRender());
alphaFineToolTipList.setModel(getDefaultListModel());
UIScrollPane scrollPane = new UIScrollPane(alphaFineToolTipList);
scrollPane.setBorder(null);
scrollPane.setBackground(Color.WHITE);
this.add(scrollPane);
this.setPreferredSize(new Dimension(640, 250));
this.setBackground(Color.WHITE);
}
public AlphaFineToolTipList getAlphaFineToolTipList() {
return alphaFineToolTipList;
}
private DefaultListModel<String> getDefaultListModel() {
DefaultListModel<String> defaultListModel = new DefaultListModel<>();
defaultListModel.addElement(AlphaFineConstants.HOT_SEARCH);
for (String content : AlphaFineConstants.HOT_SEARCH_SET) {
defaultListModel.addElement(content);
}
return defaultListModel;
}
public void refreshHistory() {
Stack<String> stack = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getHistorySearch();
if (stack.isEmpty()) {
return;
}
DefaultListModel<String> defaultListModel = new DefaultListModel<>();
for (int i = stack.size() - 1; i >= 0; i--) {
defaultListModel.addElement(stack.get(i));
}
// defaultListModel.addElement(StringUtils.EMPTY);
defaultListModel.addElement(AlphaFineConstants.HOT_SEARCH);
for (String content : AlphaFineConstants.HOT_SEARCH_SET) {
defaultListModel.addElement(content);
}
alphaFineToolTipList.setModel(defaultListModel);
}
}

32
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/LineCellRender.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ilable.UILabel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public class LineCellRender implements ListCellRenderer<String> {
@Override
public Component getListCellRendererComponent(JList<? extends String> list, String value, int index,
boolean isSelected, boolean cellHasFocus) {
JPanel panel = new JPanel(new BorderLayout());
UILabel splitLabel = new UILabel();
panel.setBackground(null);
splitLabel.setBackground(UIConstants.BARNOMAL);
splitLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 5,0));
panel.setPreferredSize(new Dimension(640, 1));
panel.add(splitLabel);
return panel;
}
}

100
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsContentCellRender.java

@ -0,0 +1,100 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineUtil;
import com.fr.design.mainframe.alphafine.model.ProductNews;
import com.fr.design.utils.DesignUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/19
*/
public class ProductNewsContentCellRender implements ListCellRenderer<Object> {
private static final String FINE_REPORT = "FineReport";
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
/**
* 透明灰色背景 Y方向偏移
*/
private static final int GRAY_BACKGROUND_Y_GAP = 39;
/**
* 透明灰色背景 高度
*/
private static final int GRAY_BACKGROUND_HEIGHT = 23;
/**
* 单行产品动态的高度与宽度尺寸
*/
private static final Dimension DEFAULT_DIMENSION = new Dimension(500, 100);
private String[] segmentationResult;
private ProductNewsList productNewsList;
public ProductNewsContentCellRender(String[] segmentationResult, ProductNewsList productNewsList) {
this.segmentationResult = segmentationResult;
this.productNewsList = productNewsList;
}
public ProductNewsContentCellRender(ProductNewsList productNewsList) {
this(null, productNewsList);
}
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
ProductNews productNews = (ProductNews) value;
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
panel.setBackground(Color.WHITE);
panel.add(new ProductNewsImagePanel(productNews), BorderLayout.WEST);
JPanel textPane = new JPanel(new BorderLayout());
textPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 0));
UILabel titleLabel = new UILabel(AlphaFineUtil.highLightModelName(productNews.getTitle(), segmentationResult));
titleLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(20));
if (productNewsList.getHoverIndex() == index) {
titleLabel.setForeground(UIConstants.FLESH_BLUE);
}
textPane.add(titleLabel, BorderLayout.NORTH);
JPanel infoPane = new JPanel(new BorderLayout());
UILabel productLabel = new UILabel(FINE_REPORT) {
@Override
protected void paintComponent(Graphics g) {
g.setColor(AlphaFineConstants.BACKGROUND_COLOR);
g.fillRect(0, getHeight() - GRAY_BACKGROUND_Y_GAP, getWidth(), GRAY_BACKGROUND_HEIGHT);
super.paintComponent(g);
}
};
productLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
infoPane.add(productLabel, BorderLayout.WEST);
UILabel dateLabel = new UILabel(DATE_FORMAT.format(productNews.getPushDate()));
dateLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
dateLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
infoPane.setBackground(Color.WHITE);
infoPane.add(dateLabel, BorderLayout.CENTER);
textPane.setBackground(Color.WHITE);
textPane.add(infoPane, BorderLayout.CENTER);
panel.add(textPane, BorderLayout.CENTER);
panel.setPreferredSize(DEFAULT_DIMENSION);
return panel;
}
}

79
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsImagePanel.java

@ -0,0 +1,79 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.base.GraphHelper;
import com.fr.base.svg.SVGLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.alphafine.model.ProductNews;
import com.fr.design.utils.SvgPaintUtils;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.util.Set;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/15
*/
public class ProductNewsImagePanel extends JPanel {
private static final Image NEW_TIP_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/new_tip.svg");
private static final int BACKGROUND_HEIGHT = 20;
private static final Color BACKGROUND_COLOR = new Color(116, 181, 249);
private static final Color COVER_COLOR = new Color(116, 181, 249, 26);
private ProductNews productNews;
private int width = 200;
private int height = 150;
public ProductNewsImagePanel(ProductNews productNews) {
this.productNews = productNews;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
Color defaultColor = g2.getColor();
Image image = productNews.getImage();
if (image != null) {
g2.drawImage(productNews.getImage(), 0, 0, getWidth(), getHeight(), this);
} else {
g2.setColor(COVER_COLOR);
g2.fillRect(0, 0, getWidth(), getHeight());
}
Set<Long> readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet();
if (!readSet.contains(productNews.getId())) {
SvgPaintUtils.beforePaint(g2);
g2.drawImage(NEW_TIP_IMAGE, 0, 0, this);
SvgPaintUtils.afterPaint(g2);
}
g2.setColor(BACKGROUND_COLOR);
g2.fillRect(0, getHeight() - BACKGROUND_HEIGHT, getWidth(), BACKGROUND_HEIGHT);
g2.setColor(Color.WHITE);
int x = (getWidth() - GraphHelper.getWidth(productNews.getTag().getDesc(), g2.getFont())) / 2;
g2.drawString(productNews.getTag().getDesc(), x, getHeight() - 5);
g2.setColor(defaultColor);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
}

78
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java

@ -0,0 +1,78 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.model.ProductNews;
import com.fr.log.FineLoggerFactory;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.net.URI;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.ListModel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/21
*/
public class ProductNewsList extends JList<ProductNews> {
private int hoverIndex = -1;
public ProductNewsList(ListModel<ProductNews> dataModel) {
super(dataModel);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == AlphaFineConstants.DEFAULT_CLICK_COUNT) {
dealWithClick();
}
}
@Override
public void mouseExited(MouseEvent e) {
hoverIndex = -1;
ProductNewsList.this.repaint();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
int index = ProductNewsList.this.locationToIndex(p);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
if (index != hoverIndex) {
hoverIndex = index;
ProductNewsList.this.repaint();
}
}
});
}
public ProductNewsList() {
this(new DefaultListModel<>());
}
private void dealWithClick() {
ProductNews productNews = getSelectedValue();
try {
Desktop.getDesktop().browse(new URI(productNews.getUrl()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet().add(productNews.getId());
AlphaFineHelper.getAlphaFineDialog().repaint();
}
public int getHoverIndex() {
return hoverIndex;
}
}

36
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsSearchResultPane.java

@ -0,0 +1,36 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/21
*/
public class ProductNewsSearchResultPane extends JPanel {
private ProductNewsList productNewsList;
public ProductNewsSearchResultPane(String[] segmentationResult) {
productNewsList = new ProductNewsList();
UIScrollPane scrollPane = new UIScrollPane(productNewsList);
scrollPane.setBackground(Color.WHITE);
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 20));
productNewsList.setCellRenderer(new ProductNewsContentCellRender(segmentationResult, productNewsList));
this.setLayout(new BorderLayout());
this.setBackground(Color.WHITE);
this.add(scrollPane);
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE);
}
public ProductNewsList getProductNewsList() {
return productNewsList;
}
}

126
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchListModel.java

@ -0,0 +1,126 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/18
*/
public class SearchListModel extends DefaultListModel<AlphaCellModel> {
private static final int MAX_SHOW_SIZE = 12;
private static final long serialVersionUID = 7230585307439551228L;
private SearchResult myDelegate;
/**
* 第一有效的项是否被选中
*/
private boolean isValidSelected;
private UIScrollPane leftSearchResultPane;
private AlphaFineList searchResultList;
public SearchListModel(SearchResult searchResult, AlphaFineList searchResultList, UIScrollPane leftSearchResultPane) {
this.myDelegate = searchResult;
this.searchResultList = searchResultList;
this.leftSearchResultPane = leftSearchResultPane;
}
@Override
public void addElement(AlphaCellModel element) {
AlphaFineHelper.checkCancel();
int index = myDelegate.size();
myDelegate.add(element);
fireContentsChanged(this, index, index);
fireSelectedStateChanged(element, index);
}
@Override
protected void fireContentsChanged(Object source, int index0, int index1) {
if (myDelegate.size() > MAX_SHOW_SIZE) {
leftSearchResultPane.getVerticalScrollBar().setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0));
leftSearchResultPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 2));
} else {
leftSearchResultPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
super.fireContentsChanged(source, index0, index1);
}
/**
* 触发选中第一有效的项
*
* @param element
* @param index
*/
private void fireSelectedStateChanged(AlphaCellModel element, int index) {
if (element.hasAction() && !isValidSelected()) {
searchResultList.setSelectedIndex(index);
setValidSelected(true);
}
}
@Override
public AlphaCellModel getElementAt(int index) {
return myDelegate.get(index);
}
@Override
public void add(int index, AlphaCellModel element) {
myDelegate.add(index, element);
fireIntervalAdded(this, index, index);
}
@Override
public AlphaCellModel remove(int index) {
AlphaCellModel object = myDelegate.get(index);
myDelegate.remove(object);
fireContentsChanged(this, index, index);
return object;
}
@Override
public int getSize() {
return this.myDelegate.size();
}
@Override
public void removeAllElements() {
this.myDelegate.clear();
}
/**
* 重置选中状态
*/
public void resetSelectedState() {
setValidSelected(false);
}
private boolean isValidSelected() {
return isValidSelected;
}
private void setValidSelected(boolean selected) {
isValidSelected = selected;
}
@Override
public boolean isEmpty() {
return myDelegate.isEmpty();
}
public void resetState() {
for (int i = 0; i < getSize(); i++) {
getElementAt(i).resetState();
}
}
}

83
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultContentCellRender.java

@ -0,0 +1,83 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineUtil;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/19
*/
public class SearchResultContentCellRender implements ListCellRenderer<Object> {
private static final int OFFSET = 45;
private static final String SELECTED_PATH = AlphaFineConstants.IMAGE_URL + "selected";
private static final String CELL_PATH = AlphaFineConstants.IMAGE_URL + "alphafine";
private static final String SUFFIX = ".png";
private String[] segmentationResult;
public SearchResultContentCellRender(String[] segmentationResult) {
this.segmentationResult = segmentationResult;
}
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
AlphaCellModel model = (AlphaCellModel) value;
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(null);
panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
// 图标icon 样式
UILabel iconLabel = new UILabel();
if (isSelected) {
iconLabel.setText(StringUtils.BLANK + model.getName());
String iconUrl = SELECTED_PATH + model.getType().getTypeValue() + SUFFIX;
panel.setBackground(AlphaFineConstants.BLUE);
iconLabel.setForeground(Color.WHITE);
iconLabel.setIcon(IOUtils.readIcon(iconUrl));
} else {
iconLabel.setText(AlphaFineUtil.highLightModelName(model.getName(), segmentationResult));
String iconUrl = CELL_PATH + model.getType().getTypeValue() + SUFFIX;
iconLabel.setIcon(IOUtils.readIcon(iconUrl));
}
iconLabel.setFont(AlphaFineConstants.MEDIUM_FONT);
// 内容详情label 样式
UILabel detailLabel = new UILabel();
String description = model.getDescription();
if (StringUtils.isNotBlank(description)) {
detailLabel.setText("-" + description);
detailLabel.setForeground(AlphaFineConstants.LIGHT_GRAY);
panel.add(detailLabel, BorderLayout.CENTER);
int width = (int) (iconLabel.getPreferredSize().getWidth() + detailLabel.getPreferredSize().getWidth());
if (width > AlphaFineConstants.LEFT_WIDTH - OFFSET) {
int nameWidth = (int) (AlphaFineConstants.LEFT_WIDTH - detailLabel.getPreferredSize().getWidth() - OFFSET);
iconLabel.setPreferredSize(new Dimension(nameWidth, AlphaFineConstants.CELL_HEIGHT));
}
} else {
iconLabel.setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH - OFFSET, AlphaFineConstants.CELL_HEIGHT));
}
panel.add(iconLabel, BorderLayout.WEST);
panel.setPreferredSize(new Dimension(list.getFixedCellWidth(), AlphaFineConstants.CELL_HEIGHT));
return panel;
}
}

51
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultPane.java

@ -0,0 +1,51 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.preview.ResultShowPane;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public class SearchResultPane extends JPanel {
private AlphaFineList searchResultList;
private SearchListModel searchListModel;
private UIScrollPane leftSearchResultPane;
public SearchResultPane(String[] segmentationResult, ResultShowPane rightSearchResultPane) {
searchResultList = new AlphaFineList();
searchResultList.setFixedCellHeight(AlphaFineConstants.CELL_HEIGHT);
leftSearchResultPane = new UIScrollPane(searchResultList);
leftSearchResultPane.setBorder(null);
leftSearchResultPane.setBackground(Color.WHITE);
leftSearchResultPane.setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH, AlphaFineConstants.CONTENT_HEIGHT));
searchListModel = new SearchListModel(new SearchResult(), searchResultList, leftSearchResultPane);
searchResultList.setModel(searchListModel);
searchResultList.setCellRenderer(new SearchResultContentCellRender(segmentationResult));
searchResultList.setResultShowPane(rightSearchResultPane);
this.setPreferredSize(AlphaFineConstants.CONTENT_SIZE);
this.setLayout(new BorderLayout());
this.add(leftSearchResultPane, BorderLayout.WEST);
this.add(rightSearchResultPane, BorderLayout.EAST);
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE);
}
public AlphaFineList getSearchResultList() {
return searchResultList;
}
public UIScrollPane getLeftSearchResultPane() {
return leftSearchResultPane;
}
}

58
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchTooltipPopup.java

@ -0,0 +1,58 @@
package com.fr.design.mainframe.alphafine.component;
import java.awt.Component;
import java.awt.Point;
import javax.swing.Popup;
import javax.swing.PopupFactory;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public class SearchTooltipPopup {
private static final SearchTooltipPopup INSTANCE = new SearchTooltipPopup();
public static SearchTooltipPopup getInstance() {
return INSTANCE;
}
private AlphaSearchTooltipPane alphaSearchTooltipPane;
private SearchTooltipPopup() {
alphaSearchTooltipPane = new AlphaSearchTooltipPane();
}
private boolean showPopup;
private Popup popup;
public void show(Component owner) {
if (popup == null || !showPopup) {
PopupFactory pf = PopupFactory.getSharedInstance();
Point point = owner.getLocationOnScreen();
alphaSearchTooltipPane.refreshHistory();
popup = pf.getPopup(owner, alphaSearchTooltipPane, point.x, point.y + owner.getHeight());
}
if (!showPopup) {
alphaSearchTooltipPane.repaint();
popup.show();
getAlphaFineToolTipList().clearSelection();
showPopup = true;
}
}
public AlphaFineToolTipList getAlphaFineToolTipList() {
return alphaSearchTooltipPane.getAlphaFineToolTipList();
}
public void hide() {
if (popup != null) {
popup.hide();
}
showPopup = false;
}
}

81
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SelectedLabel.java

@ -0,0 +1,81 @@
package com.fr.design.mainframe.alphafine.component;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineUtil;
import com.fr.design.mainframe.alphafine.CellType;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/07
*/
public class SelectedLabel extends UILabel {
private static final int WIDTH = 4;
private static final int HEIGHT = 4;
private static final int GAP = 0;
private static final int BORDER_RIGHT = 5;
private static final int BORDER_TOP = 2;
private boolean selected;
private CellType cellType;
public SelectedLabel(String text, CellType cellType, boolean selected) {
super(text);
this.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8);
this.setBorder(BorderFactory.createEmptyBorder(BORDER_TOP, 0, 0, BORDER_RIGHT));
this.selected = selected;
this.cellType = cellType;
}
public SelectedLabel(String text, CellType cellType) {
this(text, cellType, false);
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (selected) {
g2d.setColor(UIConstants.FLESH_BLUE);
setForeground(UIConstants.FLESH_BLUE);
g2d.drawLine(0, this.getHeight() - 1, this.getWidth() - BORDER_RIGHT, this.getHeight() - 1);
}
super.paintComponent(g);
}
@Override
protected void paintBorder(Graphics g) {
super.paintBorder(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (cellType == CellType.PRODUCT_NEWS && AlphaFineUtil.unread()) {
Color oldColor = g.getColor();
g2d.setColor(Color.RED);
g2d.fillOval(getWidth() - WIDTH, GAP, WIDTH, HEIGHT);
g2d.setColor(oldColor);
}
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public CellType getCellType() {
return cellType;
}
}

14
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/exception/AlphaFineNetworkException.java

@ -0,0 +1,14 @@
package com.fr.design.mainframe.alphafine.exception;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/27
*/
public class AlphaFineNetworkException extends RuntimeException {
public AlphaFineNetworkException() {
super("NetWork Error");
}
}

200
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java

@ -0,0 +1,200 @@
package com.fr.design.mainframe.alphafine.model;
import com.fr.design.i18n.Toolkit;
import java.awt.Image;
import java.util.Date;
/**
* 产品动态
*
* @author hades
* @version 11.0
* Created by hades on 2022/4/05
*/
public class ProductNews {
private long id;
private String title;
private Tag tag;
private Target target;
private Status status;
private String url;
private Image image;
private Date pushDate;
/**
* 创建cid的用户
*/
private int creator;
public long getId() {
return id;
}
public ProductNews setId(long id) {
this.id = id;
return this;
}
public String getTitle() {
return title;
}
public ProductNews setTitle(String title) {
this.title = title;
return this;
}
public Tag getTag() {
return tag;
}
public ProductNews setTag(Tag tag) {
this.tag = tag;
return this;
}
public Target getTarget() {
return target;
}
public ProductNews setTarget(Target target) {
this.target = target;
return this;
}
public Status getStatus() {
return status;
}
public ProductNews setStatus(Status status) {
this.status = status;
return this;
}
public String getUrl() {
return url;
}
public ProductNews setUrl(String url) {
this.url = url;
return this;
}
public Image getImage() {
return image;
}
public ProductNews setImage(Image image) {
this.image = image;
return this;
}
public Date getPushDate() {
return pushDate;
}
public ProductNews setPushDate(Date pushDate) {
this.pushDate = pushDate;
return this;
}
public int getCreator() {
return creator;
}
public ProductNews setCreator(int creator) {
this.creator = creator;
return this;
}
interface CodeParser {
int getCode();
}
public enum Status implements CodeParser {
STOP(0), START(1);
private final int code;
Status(int code) {
this.code = code;
}
@Override
public int getCode() {
return code;
}
public static Status parseCode(int code) {
for (Status status : values()) {
if (code == status.code) {
return status;
}
}
throw new IllegalArgumentException();
}
}
public enum Tag {
SOLUTION(1, Toolkit.i18nText("Fine-Design_Report_AlphaFine_Solution")),
MATERIAL(2, Toolkit.i18nText("Fine-Design_Report_AlphaFine_Material")),
NEW_PRODUCT(3, Toolkit.i18nText("Fine-Design_Report_AlphaFine_New_Product"));
private final int code;
private final String desc;
Tag(int code, String desc) {
this.code = code;
this.desc = desc;
}
public static Tag parseCode(int code) {
for (Tag tag :values()) {
if (tag.code == code) {
return tag;
}
}
throw new IllegalArgumentException();
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
public enum Target {
ALL_USER(0);
private final int code;
Target(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public static Target parseCode(int code) {
for (Target target : values()) {
if (target.code == code) {
return target;
}
}
throw new IllegalArgumentException();
}
}
}

121
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/DefaultProductNewsPane.java

@ -0,0 +1,121 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.component.ProductNewsContentCellRender;
import com.fr.design.mainframe.alphafine.component.ProductNewsList;
import com.fr.design.mainframe.alphafine.exception.AlphaFineNetworkException;
import com.fr.design.mainframe.alphafine.model.ProductNews;
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager;
import com.fr.design.utils.DesignUtils;
import com.fr.log.FineLoggerFactory;
import java.awt.BorderLayout;
import java.awt.Color;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/14
*/
public class DefaultProductNewsPane extends JPanel {
private static final String LOADING = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Loading");
private static final ImageIcon LOADING_ICON = new ImageIcon(DefaultProductNewsPane.class.getResource("/com/fr/web/images/loading-local.gif"));
private SwingWorker<List<ProductNews>, Void> worker;
public DefaultProductNewsPane() {
setLayout(new BorderLayout());
this.add(createLoadingPane());
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE);
this.worker = createWorker();
this.worker.execute();
}
private JPanel createLoadingPane() {
JPanel loadingPane = new JPanel(new BorderLayout());
UILabel loadingLabel = new UILabel(LOADING);
loadingLabel.setForeground(AlphaFineConstants.MEDIUM_GRAY);
loadingLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(14));
loadingLabel.setBorder(BorderFactory.createEmptyBorder(0, 280, 0, 0));
UILabel loadingIconLabel = new UILabel(LOADING_ICON);
loadingIconLabel.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0));
loadingPane.add(loadingIconLabel, BorderLayout.NORTH);
loadingPane.add(loadingLabel, BorderLayout.CENTER);
loadingPane.setBackground(Color.WHITE);
return loadingPane;
}
private SwingWorker<List<ProductNews>, Void> createWorker() {
if (this.worker != null && !this.worker.isDone()) {
this.worker.cancel(true);
this.worker = null;
}
return new SwingWorker<List<ProductNews>, Void>() {
@Override
protected List<ProductNews> doInBackground() throws Exception {
if (!AlphaFineHelper.isNetworkOk()) {
throw new AlphaFineNetworkException();
}
return ProductNewsSearchManager.getInstance().getProductNewsList();
}
@Override
protected void done() {
DefaultProductNewsPane.this.removeAll();
try {
DefaultProductNewsPane.this.add(createContentPane(get()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
if (e.getCause() instanceof AlphaFineNetworkException) {
DefaultProductNewsPane.this.add(new NetWorkFailedPane(() -> {
DefaultProductNewsPane.this.removeAll();
add(createLoadingPane());
refresh();
worker = createWorker();
worker.execute();
}));
}
}
refresh();
}
};
}
private void refresh() {
this.validate();
this.repaint();
if (AlphaFineHelper.getAlphaFineDialog() != null) {
AlphaFineHelper.getAlphaFineDialog().repaint();
}
}
private UIScrollPane createContentPane(List<ProductNews> productNewsList) {
DefaultListModel<ProductNews> productNewsDefaultListModel = new DefaultListModel<>();
for (ProductNews productNews : productNewsList) {
productNewsDefaultListModel.addElement(productNews);
}
ProductNewsList productNewsJList = new ProductNewsList(productNewsDefaultListModel);
productNewsJList.setBackground(Color.WHITE);
productNewsJList.setCellRenderer(new ProductNewsContentCellRender(productNewsJList));
UIScrollPane scrollPane = new UIScrollPane(productNewsJList);
scrollPane.setBackground(Color.WHITE);
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 20));
return scrollPane;
}
}

167
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/HelpDocumentNoResultPane.java

@ -0,0 +1,167 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.utils.BrowseUtils;
import com.fr.design.utils.DesignUtils;
import com.fr.json.JSON;
import com.fr.json.JSONArray;
import com.fr.json.JSONFactory;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/13
*/
public class HelpDocumentNoResultPane extends JPanel {
private static final String RECOMMEND = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Recommend_For_You");
private static final Color DOT_COLOR = new Color(200, 201, 205);
private SwingWorker<Boolean, Void> worker;
private String title;
private Icon icon;
private Map<String, String> linkMap;
public HelpDocumentNoResultPane(String title, Icon icon) {
this.title = title;
this.icon = icon;
this.linkMap = generateMap();
setLayout(new BorderLayout());
worker = createWorker();
worker.execute();
}
private SwingWorker<Boolean, Void> createWorker() {
if (this.worker != null && !this.worker.isDone()) {
this.worker.cancel(true);
this.worker = null;
}
return new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return AlphaFineHelper.isNetworkOk();
}
@Override
protected void done() {
HelpDocumentNoResultPane.this.removeAll();
try {
if (get()) {
add(new NoResultPane(title, icon, 150), BorderLayout.CENTER);
add(createRecommendPane(linkMap), BorderLayout.EAST);
} else {
add(new NetWorkFailedPane(() -> {
worker = createWorker();
worker.execute();
}));
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
refresh();
}
};
}
private void refresh() {
this.validate();
this.repaint();
}
private Map<String, String> generateMap() {
JSONArray jsonArray = JSONFactory.createJSON(JSON.ARRAY, AlphaFineConstants.ALPHA_HELP_RECOMMEND);
Map<String, String> linkMap = new LinkedHashMap<>();
for (int i = 0, len = jsonArray.size(); i < len; i++) {
JSONObject json = jsonArray.getJSONObject(i);
linkMap.put(json.getString("name"), json.getString("link"));
}
return linkMap;
}
private JPanel createRecommendPane(Map<String, String> linkMap) {
JPanel wrapRecommendPane = new JPanel(new BorderLayout());
wrapRecommendPane.setPreferredSize(new Dimension(200, 305));
JPanel recommendPane = new JPanel();
recommendPane.setLayout(new GridLayout(0, 1));
recommendPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 130, 0));
recommendPane.setBackground(Color.WHITE);
recommendPane.add(new UILabel(RECOMMEND));
for (Map.Entry<String, String> entry : linkMap.entrySet()) {
recommendPane.add(createListLabel(entry.getKey(), entry.getValue()));
}
// 分割线
JSeparator sep = new JSeparator();
sep.setOrientation(JSeparator.VERTICAL);
sep.setLayout(new GridLayout(0, 1));
sep.setPreferredSize(new Dimension(1, 285));
sep.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
sep.add(new UILabel());
wrapRecommendPane.add(sep, BorderLayout.WEST);
wrapRecommendPane.add(recommendPane, BorderLayout.CENTER);
return wrapRecommendPane;
}
private JPanel createListLabel(String text, String link) {
UILabel listLabel = new UILabel(String.format("%s", text));
listLabel.setForeground(UIConstants.FLESH_BLUE);
listLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
listLabel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
responseClick(link);
}
});
listLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
JPanel listPane = new JPanel(new BorderLayout());
listPane.setBackground(Color.WHITE);
UILabel dotLabel = new UILabel("·");
dotLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
dotLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(14));
dotLabel.setHorizontalAlignment(SwingConstants.LEADING);
dotLabel.setForeground(DOT_COLOR);
listPane.add(dotLabel, BorderLayout.WEST);
listPane.add(listLabel, BorderLayout.CENTER);
listPane.setPreferredSize(new Dimension(100, 20));
return listPane;
}
/**
* 方便记录埋点
*
* @param link
*/
private void responseClick(String link) {
BrowseUtils.browser(link);
}
}

167
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/LoadingRightSearchResultPane.java

@ -0,0 +1,167 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.cell.model.FileModel;
import com.fr.design.mainframe.alphafine.cell.model.PluginModel;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.exporter.LocalExportOperator;
import com.fr.workspace.server.exporter.TemplateExportOperator;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.SwingWorker;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/20
*/
public class LoadingRightSearchResultPane extends ResultShowPane {
private SwingWorker<BufferedImage, Void> showWorker;
public LoadingRightSearchResultPane() {
this.setBackground(Color.WHITE);
this.setPreferredSize(new Dimension(AlphaFineConstants.RIGHT_WIDTH - 1, AlphaFineConstants.CONTENT_HEIGHT));
initLoadingLabel();
}
private void initLoadingLabel() {
UILabel label = new UILabel(new ImageIcon(getClass().getResource("/com/fr/design/mainframe/alphafine/images/opening.gif")));
label.setBorder(BorderFactory.createEmptyBorder(120, 0, 0, 0));
this.add(label, BorderLayout.CENTER);
}
private void showDefaultPreviewPane() {
this.removeAll();
initLoadingLabel();
validate();
repaint();
revalidate();
}
@Override
public void showResult(AlphaCellModel selectedValue) {
showDefaultPreviewPane();
checkWorker();
if (selectedValue.getType() == CellType.FILE) {
fileShowWorker(selectedValue);
}
if (selectedValue.getType() == CellType.PLUGIN) {
pluginShowWorker(selectedValue);
}
this.showWorker.execute();
}
private void fileShowWorker(AlphaCellModel selectedValue) {
this.showWorker = new SwingWorker<BufferedImage, Void>() {
@Override
protected BufferedImage doInBackground() throws Exception {
final String fileName = ((FileModel) selectedValue).getFilePath().substring(ProjectConstants.REPORTLETS_NAME.length() + 1);
if (fileName.endsWith(ProjectConstants.FRM_SUFFIX)) {
return frmToImage(fileName);
} else if (fileName.endsWith(ProjectConstants.CPT_SUFFIX)) {
return cptToImage(fileName);
} else {
return null;
}
}
@Override
protected void done() {
if (!isCancelled()) {
LoadingRightSearchResultPane.this.removeAll();
try {
LoadingRightSearchResultPane.this.add(new FilePreviewPane(get()));
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
validate();
repaint();
}
}
};
}
private void pluginShowWorker(AlphaCellModel selectedValue) {
this.showWorker = new SwingWorker<BufferedImage, Void>() {
@Override
protected BufferedImage doInBackground() {
BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(new URL(((PluginModel) selectedValue).getImageUrl()));
} catch (IOException e) {
try {
bufferedImage = ImageIO.read(getClass().getResource("/com/fr/design/mainframe/alphafine/images/default_product.png"));
} catch (IOException e1) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return bufferedImage;
}
@Override
protected void done() {
try {
if (!isCancelled()) {
LoadingRightSearchResultPane.this.removeAll();
LoadingRightSearchResultPane.this.add(new PluginPreviewPane((selectedValue).getName(), get(), ((PluginModel) selectedValue).getVersion(), ((PluginModel) selectedValue).getJartime(), ((PluginModel) selectedValue).getType(), ((PluginModel) selectedValue).getPrice()));
validate();
repaint();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
};
}
private BufferedImage frmToImage(String fileName) throws Exception {
byte[] bytes = null;
try {
bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportFormAsImageData(fileName);
} catch (Exception ignored) {
// 兼容下老版本
bytes = new LocalExportOperator().exportFormAsImageData(fileName);
}
return TemplateExportOperator.byteDataToImage(bytes);
}
private BufferedImage cptToImage(String fileName) throws Exception {
byte[] bytes = null;
try {
bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportWorkBookAsImageData(fileName);
} catch (Exception ignored) {
// 兼容下老版本
bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName);
}
return TemplateExportOperator.byteDataToImage(bytes);
}
private void checkWorker() {
if (this.showWorker != null && !this.showWorker.isDone()) {
this.showWorker.cancel(true);
this.showWorker = null;
}
}
}

69
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NetWorkFailedPane.java

@ -0,0 +1,69 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.share.ui.base.MouseClickListener;
import com.fr.general.IOUtils;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/28
*/
public class NetWorkFailedPane extends JPanel {
private Runnable reload;
public NetWorkFailedPane() {
this(() -> {});
}
public NetWorkFailedPane(Runnable reload) {
this.reload = reload;
this.setLayout(new BorderLayout());
this.add(createInternetErrorPane());
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE);
this.setBackground(Color.WHITE);
}
private JPanel createInternetErrorPane() {
JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5);
panel.setBackground(Color.WHITE);
UILabel imagePanel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/internet_error.png"));
imagePanel.setBorder(BorderFactory.createEmptyBorder(50, 280, 0, 0));
panel.add(imagePanel);
UILabel uiLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed"));
uiLabel.setBorder(BorderFactory.createEmptyBorder(0, 300, 0, 0));
uiLabel.setForeground(Color.decode("#8F8F92"));
UILabel reloadLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Online_Reload"));
reloadLabel.setBorder(BorderFactory.createEmptyBorder(0, 310, 0, 0));
reloadLabel.setForeground(Color.decode("#419BF9"));
reloadLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
reloadLabel.addMouseListener(new MouseClickListener() {
@Override
public void mousePressed(MouseEvent e) {
reload.run();
}
});
panel.add(uiLabel);
panel.add(reloadLabel);
return panel;
}
private UILabel tipLabel(String text) {
UILabel tipLabel = new UILabel(text);
tipLabel.setHorizontalAlignment(SwingConstants.CENTER);
return tipLabel;
}
}

23
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultPane.java

@ -1,11 +1,12 @@
package com.fr.design.mainframe.alphafine.preview;
import com.bulenkov.iconloader.IconLoader;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.utils.DesignUtils;
import java.awt.Component;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
@ -16,21 +17,29 @@ import java.awt.Dimension;
* Created by XiaXiang on 2017/8/14.
*/
public class NoResultPane extends JPanel {
public NoResultPane(String title, String iconUrl) {
public NoResultPane(String title, Icon icon) {
this(title, icon, AlphaFineConstants.LEFT_WIDTH);
}
public NoResultPane(String title, Icon icon, int width) {
setLayout(new BorderLayout());
setBackground(Color.white);
setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH, AlphaFineConstants.CONTENT_HEIGHT));
setPreferredSize(new Dimension(width, 305));
UILabel image = new UILabel();
image.setPreferredSize(new Dimension(150, 111));
image.setHorizontalAlignment(SwingConstants.CENTER);
image.setIcon(IconLoader.getIcon(iconUrl));
image.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0));
image.setIcon(icon);
image.setBorder(BorderFactory.createEmptyBorder(30, 0, 0, 0));
add(image, BorderLayout.CENTER);
add(generateDescription(title), BorderLayout.SOUTH);
}
protected Component generateDescription(String title) {
UILabel description = new UILabel(title);
description.setForeground(AlphaFineConstants.MEDIUM_GRAY);
description.setFont(DesignUtils.getDefaultGUIFont().applySize(14));
description.setBorder(BorderFactory.createEmptyBorder(0, 0, 135, 0));
description.setHorizontalAlignment(SwingConstants.CENTER);
add(image, BorderLayout.CENTER);
add(description, BorderLayout.SOUTH);
return description;
}
}

63
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultWithLinkPane.java

@ -0,0 +1,63 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.utils.BrowseUtils;
import com.fr.design.utils.DesignUtils;
import java.awt.Color;
import java.awt.Component;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
/**
* 带跳转链接的无结果面板
*
* @author hades
* @version 11.0
* Created by hades on 2022/4/12
*/
public class NoResultWithLinkPane extends NoResultPane {
private static final String TAG_A_START = "<a>";
private static final String TAG_A_END = "</a>";
public NoResultWithLinkPane(String title, Icon icon) {
super(title, icon);
}
@Override
protected Component generateDescription(String title) {
String[] para1 = title.split(TAG_A_START);
String[] para2 = para1[1].split(TAG_A_END);
MessageWithLink messageWithLink = new MessageWithLink(para1[0], para2[0], AlphaFineConstants.ALPHA_GO_TO_FORUM, para2[1], Color.WHITE, DesignUtils.getDefaultGUIFont().applySize(14), AlphaFineConstants.MEDIUM_GRAY) {
@Override
protected void initListener(String link) {
addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
jumpToForum(link);
}
}
});
}
};
messageWithLink.setBorder(BorderFactory.createEmptyBorder(0, AlphaFineConstants.LEFT_WIDTH - 30, 135, 0));
return messageWithLink;
}
/**
* 方便记录埋点
*
* @param link
*/
private void jumpToForum(String link) {
BrowseUtils.browser(link);
}
}

14
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/ResultShowPane.java

@ -0,0 +1,14 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public abstract class ResultShowPane extends JPanel {
public abstract void showResult(AlphaCellModel selectedValue);
}

27
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SearchLoadingPane.java

@ -0,0 +1,27 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/21
*/
public class SearchLoadingPane extends JPanel {
private static final ImageIcon LOADING_ICON = new ImageIcon(SearchLoadingPane.class.getResource("/com/fr/design/mainframe/alphafine/images/opening.gif"));
public SearchLoadingPane() {
setLayout(new BorderLayout());
this.add(new UILabel(LOADING_ICON));
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE);
this.setBackground(Color.WHITE);
}
}

32
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SimpleRightSearchResultPane.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.alphafine.preview;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/20
*/
public class SimpleRightSearchResultPane extends ResultShowPane {
public SimpleRightSearchResultPane(JPanel contentPane) {
this.add(contentPane);
this.setBackground(Color.WHITE);
this.setPreferredSize(new Dimension(AlphaFineConstants.RIGHT_WIDTH - 1, AlphaFineConstants.CONTENT_HEIGHT));
}
@Override
public void showResult(AlphaCellModel selectedValue) {
if (selectedValue.getType() == CellType.DOCUMENT) {
this.removeAll();
this.add(new DocumentPreviewPane((selectedValue).getName(), (selectedValue).getContent()));
validate();
repaint();
}
}
}

60
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java

@ -0,0 +1,60 @@
package com.fr.design.mainframe.alphafine.question;
import com.fr.base.svg.SVGIcon;
import com.fr.base.svg.SVGLoader;
import com.fr.base.svg.SystemScaleUtils;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.alphafine.AlphaFineUtil;
import com.fr.design.utils.SvgPaintUtils;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.JPanel;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/15
*/
public class QuestionPane extends JPanel {
private static final Image NEW_MESSAGE_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/group_new.svg");
private static final Image QUESTION_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/group.svg");
private static final Image QUESTION_BACKGROUND_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg");
public QuestionPane() {
this.setBackground(new Color(0, 0, 0, 0));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
SvgPaintUtils.beforePaint(g2);
// 宽高保持
int width = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getWidth() * SVGIcon.SYSTEM_SCALE) : getWidth();
int height = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getHeight() * SVGIcon.SYSTEM_SCALE) : getHeight();
if (AlphaFineUtil.unread() && DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isProductDynamics()) {
g2.drawImage(NEW_MESSAGE_IMAGE, 0, 0, this);
} else {
g2.drawImage(QUESTION_BACKGROUND_IMAGE, 0, 0, this);
}
int imageWidth = QUESTION_IMAGE.getWidth(this);
int imageHeight = QUESTION_IMAGE.getHeight(this);
g2.drawImage(QUESTION_IMAGE, (width - imageWidth) / 2 - 2, (height - imageHeight) / 2 - 2,this);
SvgPaintUtils.afterPaint(g2);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(40, 40);
}
}

84
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionWindow.java

@ -0,0 +1,84 @@
package com.fr.design.mainframe.alphafine.question;
import com.fr.design.DesignerEnvManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JWindow;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/15
*/
public class QuestionWindow extends JWindow {
private static final QuestionWindow INSTANCE = new QuestionWindow();
private final QuestionPane questionPane = new QuestionPane();
private int pressX;
private int pressY;
private QuestionWindow() {
this.setBackground(new Color(0, 0, 0, 0));
questionPane.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
AlphaFineHelper.showAlphaFineDialog(true);
}
@Override
public void mousePressed(MouseEvent e) {
pressX = e.getX();
pressY = e.getY();
}
});
questionPane.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
int left = getLocation().x;
int top = getLocation().y;
setLocation(left + e.getX() - pressX, top + e.getY() - pressY);
}
});
DesignerContext.getDesignerFrame().addWindowListener(new WindowAdapter() {
@Override
public void windowActivated(WindowEvent e) {
QuestionWindow.getInstance().setVisible(true);
}
@Override
public void windowDeactivated(WindowEvent e) {
QuestionWindow.getInstance().dispose();
QuestionWindow.getInstance().setVisible(false);
}
});
questionPane.setToolTipText(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Learn_More_About"));
this.setContentPane(questionPane);
this.setSize(new Dimension(40, 40));
// 这个地方可以设置alwaysOnTop 弹窗会跟随主页面失去激活状态而隐藏 不会与其他弹窗冲突
this.setAlwaysOnTop(true);
this.setLocation(DesignerContext.getDesignerFrame().getWidth() - 100,
DesignerContext.getDesignerFrame().getHeight() - 100);
}
@Override
public void setVisible(boolean visible) {
if (visible && !DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) {
return;
}
super.setVisible(visible);
}
public static QuestionWindow getInstance() {
return INSTANCE;
}
}

127
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/ProductNewsSearchWorkerManager.java

@ -0,0 +1,127 @@
package com.fr.design.mainframe.alphafine.search;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.component.AlphaFineFrame;
import com.fr.design.mainframe.alphafine.component.ProductNewsSearchResultPane;
import com.fr.design.mainframe.alphafine.model.ProductNews;
import com.fr.log.FineLoggerFactory;
import java.util.List;
import java.util.function.Function;
import javax.swing.DefaultListModel;
import javax.swing.SwingWorker;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/22
*/
public class ProductNewsSearchWorkerManager implements SearchManager {
private final CellType cellType;
private SwingWorker<DefaultListModel<ProductNews>, Void> searchWorker;
private Function<SearchTextBean, List<ProductNews>> searchFunction;
private ProductNewsSearchResultPane searchResultPane;
private AlphaFineFrame alphaFineFrame;
private volatile boolean hasSearchResult = true;
private volatile boolean searchOver = false;
private volatile boolean networkError = false;
public ProductNewsSearchWorkerManager(CellType cellType, Function<SearchTextBean, List<ProductNews>> searchFunction, AlphaFineFrame alphaFineFrame) {
this.cellType = cellType;
this.searchFunction = searchFunction;
this.alphaFineFrame = alphaFineFrame;
}
@Override
public void doSearch(SearchTextBean searchTextBean) {
checkSearchWork();
searchOver = false;
networkError = false;
if (searchResultPane != null) {
alphaFineFrame.removeSearchResultPane(searchResultPane);
}
searchResultPane = new ProductNewsSearchResultPane(searchTextBean.getSegmentation());
alphaFineFrame.addResult(searchResultPane, cellType.getFlagStr4Result());
this.searchWorker = new SwingWorker<DefaultListModel<ProductNews>, Void>() {
@Override
protected DefaultListModel<ProductNews> doInBackground() throws Exception {
DefaultListModel<ProductNews> productNewsDefaultListModel = new DefaultListModel<>();
if (!AlphaFineHelper.isNetworkOk() && cellType.isNeedNetWork()) {
networkError = true;
FineLoggerFactory.getLogger().warn("alphaFine network error");
return productNewsDefaultListModel;
}
List<ProductNews> productNewsList = searchFunction.apply(searchTextBean);
for (ProductNews productNews : productNewsList) {
productNewsDefaultListModel.addElement(productNews);
}
return productNewsDefaultListModel;
}
@Override
protected void done() {
searchOver = true;
if (!isCancelled()) {
try {
if (networkError) {
alphaFineFrame.showResult(AlphaFineConstants.NETWORK_ERROR);
return;
}
DefaultListModel<ProductNews> productNewsDefaultListModel = get();
hasSearchResult = !productNewsDefaultListModel.isEmpty();
searchResultPane.getProductNewsList().setModel(get());
if (alphaFineFrame.getSelectedType() == cellType) {
if (!hasSearchResult) {
alphaFineFrame.showResult(CellType.NO_RESULT.getFlagStr4None());
return;
}
alphaFineFrame.showResult(cellType.getFlagStr4Result());
searchResultPane.getProductNewsList().setSelectedIndex(0);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
};
this.searchWorker.execute();
}
public ProductNewsSearchResultPane getSearchResultPane() {
return searchResultPane;
}
@Override
public boolean hasSearchResult() {
return hasSearchResult;
}
@Override
public boolean isSearchOver() {
return searchOver;
}
private void checkSearchWork() {
if (this.searchWorker != null && !this.searchWorker.isDone()) {
this.searchWorker.cancel(true);
this.searchWorker = null;
}
}
@Override
public boolean isNetWorkError() {
return networkError;
}
}

17
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchManager.java

@ -0,0 +1,17 @@
package com.fr.design.mainframe.alphafine.search;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/17
*/
public interface SearchManager {
void doSearch(SearchTextBean searchTextBean);
boolean hasSearchResult();
boolean isSearchOver();
boolean isNetWorkError();
}

37
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchTextBean.java

@ -0,0 +1,37 @@
package com.fr.design.mainframe.alphafine.search;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/17
*/
public class SearchTextBean {
private String searchText;
/**
* 分词搜索
*/
private String[] segmentation;
public SearchTextBean(String searchText, String[] segmentation) {
this.searchText = searchText;
this.segmentation = segmentation;
}
public String getSearchText() {
return searchText;
}
public void setSearchText(String searchText) {
this.searchText = searchText;
}
public String[] getSegmentation() {
return segmentation;
}
public void setSegmentation(String[] segmentation) {
this.segmentation = segmentation;
}
}

146
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchWorkerManager.java

@ -0,0 +1,146 @@
package com.fr.design.mainframe.alphafine.search;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.component.AlphaFineFrame;
import com.fr.design.mainframe.alphafine.component.AlphaFineList;
import com.fr.design.mainframe.alphafine.component.SearchListModel;
import com.fr.design.mainframe.alphafine.component.SearchResultPane;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.preview.ResultShowPane;
import com.fr.log.FineLoggerFactory;
import java.util.function.Function;
import javax.swing.SwingWorker;
import org.jetbrains.annotations.Nullable;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/4/16
*/
public class SearchWorkerManager implements SearchManager {
private final CellType cellType;
private SwingWorker<SearchListModel, Void> searchWorker;
private Function<SearchTextBean, SearchResult> searchResultFunction;
private SearchResultPane searchResultPane;
private AlphaFineFrame alphaFineFrame;
private ResultShowPane resultShowPane;
private volatile boolean hasSearchResult = true;
private volatile boolean searchOver = false;
private volatile boolean networkError = false;
public SearchWorkerManager(CellType cellType, Function<SearchTextBean, SearchResult> function, AlphaFineFrame alphaFineFrame, ResultShowPane resultShowPane) {
this.cellType = cellType;
this.searchResultFunction = function;
this.alphaFineFrame = alphaFineFrame;
this.resultShowPane = resultShowPane;
}
private void initSearchResult(SearchTextBean searchTextBean) {
if (searchResultPane != null) {
alphaFineFrame.removeSearchResultPane(searchResultPane);
}
searchResultPane = new SearchResultPane(searchTextBean.getSegmentation(), resultShowPane);
alphaFineFrame.addResult(searchResultPane, cellType.getFlagStr4Result());
}
private void checkSearchWork() {
if (this.searchWorker != null && !this.searchWorker.isDone()) {
this.searchWorker.cancel(true);
this.searchWorker = null;
}
}
private void initSearchWorker(SearchTextBean searchTextBean) {
this.searchOver = false;
this.networkError = false;
this.searchWorker = new SwingWorker<SearchListModel, Void>() {
@Override
protected SearchListModel doInBackground() throws Exception {
SearchListModel searchListModel = new SearchListModel(new SearchResult(), searchResultPane.getSearchResultList(), searchResultPane.getLeftSearchResultPane());
if (!AlphaFineHelper.isNetworkOk() && cellType.isNeedNetWork()) {
networkError = true;
FineLoggerFactory.getLogger().warn("alphaFine network error");
return searchListModel;
}
SearchResult searchResult = searchResultFunction.apply(searchTextBean);
for (AlphaCellModel object : searchResult) {
AlphaFineHelper.checkCancel();
searchListModel.addElement(object);
}
return searchListModel;
}
@Override
protected void done() {
searchOver = true;
if (!isCancelled()) {
try {
if (networkError) {
alphaFineFrame.showResult(AlphaFineConstants.NETWORK_ERROR);
return;
}
SearchListModel searchListModel = get();
hasSearchResult = !searchListModel.isEmpty();
searchResultPane.getSearchResultList().setModel(get());
if (alphaFineFrame.getSelectedType() == cellType) {
if (!hasSearchResult) {
alphaFineFrame.showResult(CellType.NO_RESULT.getFlagStr4None());
return;
}
alphaFineFrame.showResult(cellType.getFlagStr4Result());
searchResultPane.getSearchResultList().setSelectedIndex(0);
searchResultPane.getSearchResultList().requestFocus();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
};
}
@Override
public void doSearch(SearchTextBean searchTextBean) {
initSearchResult(searchTextBean);
checkSearchWork();
initSearchWorker(searchTextBean);
this.searchWorker.execute();
}
@Override
public boolean hasSearchResult() {
return hasSearchResult;
}
@Override
public boolean isSearchOver() {
return searchOver;
}
@Override
public boolean isNetWorkError() {
return networkError;
}
@Nullable
public AlphaFineList getSearchResultList() {
if (searchResultPane != null) {
return searchResultPane.getSearchResultList();
}
return null;
}
}

12
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/fun/AlphaFineSearchProvider.java

@ -1,6 +1,7 @@
package com.fr.design.mainframe.alphafine.search.manager.fun;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.search.SearchTextBean;
/**
* Created by XiaXiang on 2017/3/27.
@ -20,4 +21,15 @@ public interface AlphaFineSearchProvider {
* @return
*/
SearchResult getMoreSearchResult(String searchText);
/**
* 获取所有搜索结果 取决于具体实现
*
* @param searchTextBean
* @return
*/
default SearchResult getSearchResult(SearchTextBean searchTextBean) {
return new SearchResult();
}
}

7
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java

@ -8,6 +8,7 @@ import com.fr.design.mainframe.alphafine.cell.model.ActionModel;
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.cell.model.MoreModel;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.search.SearchTextBean;
import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider;
import com.fr.design.mainframe.toolbar.UpdateActionManager;
import com.fr.design.mainframe.toolbar.UpdateActionModel;
@ -101,4 +102,10 @@ public class ActionSearchManager implements AlphaFineSearchProvider {
public SearchResult getMoreSearchResult(String searchText) {
return moreModelList;
}
@Override
public SearchResult getSearchResult(SearchTextBean searchTextBean) {
getLessSearchResult(searchTextBean.getSegmentation());
return filterModelList;
}
}

13
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java

@ -7,6 +7,7 @@ import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.cell.model.DocumentModel;
import com.fr.design.mainframe.alphafine.cell.model.MoreModel;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.search.SearchTextBean;
import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONArray;
@ -15,7 +16,6 @@ import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import java.io.IOException;
/**
* Created by XiaXiang on 2017/3/27.
@ -24,6 +24,7 @@ public class DocumentSearchManager implements AlphaFineSearchProvider {
private static volatile DocumentSearchManager instance;
private SearchResult lessModelList;
private SearchResult moreModelList;
private SearchResult searchResult;
public static DocumentSearchManager getInstance() {
if (instance == null) {
@ -54,6 +55,7 @@ public class DocumentSearchManager implements AlphaFineSearchProvider {
public SearchResult getLessSearchResult(String[] searchText) {
lessModelList = new SearchResult();
moreModelList = new SearchResult();
searchResult = new SearchResult();
if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isContainDocument()) {
if (ArrayUtils.isEmpty(searchText)) {
lessModelList.add(new MoreModel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help")));
@ -63,7 +65,7 @@ public class DocumentSearchManager implements AlphaFineSearchProvider {
if(noConnectList != null){
return noConnectList;
}
SearchResult searchResult = new SearchResult();
searchResult = new SearchResult();
for (int j = 0; j < searchText.length; j++) {
String url = AlphaFineConstants.DOCUMENT_SEARCH_URL + searchText[j];
try {
@ -81,6 +83,8 @@ public class DocumentSearchManager implements AlphaFineSearchProvider {
}
}
}
} catch (JSONException jsonException) {
FineLoggerFactory.getLogger().warn(jsonException, jsonException.getMessage());
} catch (Exception e) {
FineLoggerFactory.getLogger().error("document search error: " + e.getMessage());
}
@ -106,4 +110,9 @@ public class DocumentSearchManager implements AlphaFineSearchProvider {
return moreModelList;
}
@Override
public SearchResult getSearchResult(SearchTextBean searchTextBean) {
getLessSearchResult(searchTextBean.getSegmentation());
return searchResult;
}
}

7
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java

@ -9,6 +9,7 @@ import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.cell.model.FileModel;
import com.fr.design.mainframe.alphafine.cell.model.MoreModel;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.search.SearchTextBean;
import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider;
import com.fr.file.filetree.FileNode;
import com.fr.file.filetree.FileNodes;
@ -114,6 +115,12 @@ public class FileSearchManager implements AlphaFineSearchProvider {
return moreModelList;
}
@Override
public SearchResult getSearchResult(SearchTextBean searchTextBean) {
getLessSearchResult(searchTextBean.getSearchText(), searchTextBean.getSegmentation());
return filterModelList;
}
private void doSearch(String searchText) {
if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isContainTemplate()) {
for (FileNode node : fileNodes) {

11
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/PluginSearchManager.java

@ -7,6 +7,7 @@ import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.mainframe.alphafine.cell.model.MoreModel;
import com.fr.design.mainframe.alphafine.cell.model.PluginModel;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.design.mainframe.alphafine.search.SearchTextBean;
import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider;
import com.fr.general.ComparatorUtils;
import com.fr.general.http.HttpToolbox;
@ -28,6 +29,7 @@ import java.net.URLEncoder;
public class PluginSearchManager implements AlphaFineSearchProvider {
private SearchResult lessModelList;
private SearchResult moreModelList;
private SearchResult searchResult;
private PluginSearchManager() {
@ -97,7 +99,7 @@ public class PluginSearchManager implements AlphaFineSearchProvider {
public SearchResult getLessSearchResult(String[] searchText) {
this.lessModelList = new SearchResult();
this.moreModelList = new SearchResult();
SearchResult searchResult = new SearchResult();
this.searchResult = new SearchResult();
if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isContainPlugin()) {
if (ArrayUtils.isEmpty(searchText)) {
lessModelList.add(new MoreModel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon")));
@ -146,4 +148,11 @@ public class PluginSearchManager implements AlphaFineSearchProvider {
public SearchResult getMoreSearchResult(String searchText) {
return this.moreModelList;
}
@Override
public SearchResult getSearchResult(SearchTextBean searchTextBean) {
getLessSearchResult(searchTextBean.getSegmentation());
return searchResult;
}
}

123
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java

@ -0,0 +1,123 @@
package com.fr.design.mainframe.alphafine.search.manager.impl;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.mainframe.alphafine.AlphaFineConstants;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.model.ProductNews;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSON;
import com.fr.json.JSONArray;
import com.fr.json.JSONFactory;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import java.awt.Image;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import org.jetbrains.annotations.Nullable;
public class ProductNewsSearchManager {
private static final ProductNewsSearchManager INSTANCE = new ProductNewsSearchManager();
private static final int TIME_GAP = 12;
private List<ProductNews> productNewsResultList;
private List<ProductNews> productNewsList = new ArrayList<>();
/**
* 单独记录一份cid的唯一id 用来判断是否已读
*/
private Set<Long> idSet = new HashSet<>();
private ScheduledExecutorService service;
private ProductNewsSearchManager() {
service = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("ProductNewsSearchManager", true));
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
getProductNewsList();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}, TIME_GAP, TIME_GAP, TimeUnit.HOURS);
}
public static ProductNewsSearchManager getInstance() {
return INSTANCE;
}
public List<ProductNews> getSearchResult(String[] searchText) {
productNewsResultList = new ArrayList<>();
try {
List<ProductNews> productNewsList = getProductNewsList();
for (ProductNews productNews : productNewsList) {
for (String str : searchText) {
if (productNews.getTitle().contains(str)) {
productNewsResultList.add(productNews);
break;
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return productNewsResultList;
}
public List<ProductNews> getProductNewsList() throws Exception {
productNewsList = new ArrayList<>();
idSet = new HashSet<>();
String jsonStr = HttpToolbox.get(AlphaFineConstants.ALPHA_CID);
AlphaFineHelper.checkCancel();
JSONObject cidJSON = JSONFactory.createJSON(JSON.OBJECT, jsonStr);
JSONArray jsonArray = cidJSON.getJSONArray("data");
for (int i = 0, size = jsonArray.size(); i < size; i++) {
JSONObject obj = jsonArray.getJSONObject(i);
ProductNews productNews = new ProductNews().
setId(obj.getLong("id")).setTitle(obj.getString("title")).
setImage(getCoverImage(obj.getString("pic"))).
setUrl(obj.getString("url")).setTag(ProductNews.Tag.parseCode(obj.getInt("tag"))).
setStatus(ProductNews.Status.parseCode(obj.getInt("status"))).setTarget(
ProductNews.Target.parseCode(obj.getInt("target"))).
setCreator(obj.getInt("creator")).setPushDate(new Date(obj.getLong("push_time")));
Date currentDate = new Date(System.currentTimeMillis());
// 推送时间check
if (productNews.getPushDate().before(currentDate)) {
productNewsList.add(productNews);
idSet.add(productNews.getId());
}
}
return productNewsList;
}
public List<ProductNews> getCachedProductNewsList() {
return productNewsList;
}
public Set<Long> getIdSet() {
return idSet;
}
@Nullable
private Image getCoverImage(String url) {
try {
return ImageIO.read(new URL(url));
} catch (Exception e) {
FineLoggerFactory.getLogger().warn("get image failed from {}", url);
FineLoggerFactory.getLogger().warn(e.getMessage(), e);
}
return null;
}
}

138
designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java

@ -7,20 +7,33 @@ import com.fr.design.EnvChangeEntrance;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceInfoContext;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.loghandler.DesignerLogger;
import com.fr.design.mainframe.share.ui.base.MouseClickListener;
import com.fr.design.mainframe.toast.DesignerToastMsgUtil;
import com.fr.design.mainframe.toast.ToastMsgDialog;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.BrowseUtils;
import com.fr.event.EventDispatcher;
import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.report.RemoteDesignConstants;
import com.fr.serialization.SerializerHelper;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.third.apache.log4j.spi.LoggingEvent;
import com.fr.third.org.apache.http.client.config.RequestConfig;
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier;
import com.fr.third.org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.third.org.apache.http.ssl.SSLContexts;
import com.fr.web.WebSocketConfig;
import com.fr.web.socketio.WebSocketProtocol;
@ -29,7 +42,6 @@ import com.fr.workspace.Workspace;
import com.fr.workspace.base.WorkspaceConstants;
import com.fr.workspace.connect.WorkspaceConnection;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.server.socket.SocketInfoOperator;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
@ -38,15 +50,21 @@ import io.socket.engineio.client.transports.Polling;
import io.socket.engineio.client.transports.WebSocket;
import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.security.KeyStore;
import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
public class DesignerSocketIO {
@ -56,18 +74,21 @@ public class DesignerSocketIO {
Disconnecting
}
private static final String WEBSOCKET_HELP_DOC = CloudCenter.getInstance().acquireUrlByKind("websocketConnect", "https://help.fanruan.com/finereport/doc-view-2512.html");
private static final String HTTPS = "https";
private static final String HTTP = "http";
private static Socket socket = null;
private static Status status = Status.Disconnected;
private static Timer disConnectHintTimer = null;
private static long disConnectHintTimerDelay = 3000;
private static final int TIMEOUT = 5000;
//维护一个当前工作环境的uri列表
private static String[] uri;
//维护一个关于uri列表的计数器
private static int count;
// 当前webSocket选择的协议
private static String currentProtocol;
private static ToastMsgDialog dialog = null;
public static void close() {
@ -109,6 +130,7 @@ public class DesignerSocketIO {
} else {
//表示所有的uri都连接不成功
FineLoggerFactory.getLogger().warn("All uris failed to connect");
showSocketDisconnectToast();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
@ -227,41 +249,35 @@ public class DesignerSocketIO {
@Override
public void call(Object... objects) {
FineLoggerFactory.getLogger().info("start disConnectHintTimer");
disConnectHintTimer = new Timer();
disConnectHintTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
/*
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒
* socket 只用推日志和通知配置变更
*/
printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}");
if (status != Status.Disconnecting) {
showConnectionLostDialog();
}
status = Status.Disconnected;
} finally {
disConnectHintTimer.cancel();
disConnectHintTimer = null;
}
}
}, disConnectHintTimerDelay);
/*
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒
* socket 只用推日志和通知配置变更
*/
printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}");
if (status != Status.Disconnecting) {
dealWithSocketDisconnect();
}
status = Status.Disconnected;
}
};
private static void showConnectionLostDialog() {
private static void dealWithSocketDisconnect() {
if (checkRPCConnect()) {
showSocketDisconnectToast();
} else {
showRPCDisconnectDialog();
}
}
private static void showSocketDisconnectToast() {
try {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(
DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"),
UIManager.getString("OptionPane.messageDialogTitle"),
JOptionPane.ERROR_MESSAGE,
UIManager.getIcon("OptionPane.errorIcon"));
EnvChangeEntrance.getInstance().chooseEnv();
if (dialog == null || !dialog.isShow()) {
dialog = DesignerToastMsgUtil.createPromptDialog(createDialogContent());
dialog.setVisible(true);
}
}
});
} catch (Exception e) {
@ -269,6 +285,57 @@ public class DesignerSocketIO {
}
}
private static JPanel createDialogContent() {
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
jPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_WebSocket_Lost_Tip")), BorderLayout.WEST);
UILabel hyperLinkLabel = new UILabel(Toolkit.i18nText("Fine-Design_WebSocket_Lost_Tip_HyperLink_Text"));
hyperLinkLabel.addMouseListener(new MouseClickListener() {
@Override
public void mouseClicked(MouseEvent e) {
BrowseUtils.browser(WEBSOCKET_HELP_DOC);
}
});
hyperLinkLabel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
hyperLinkLabel.setForeground(Color.BLUE);
hyperLinkLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
jPanel.add(hyperLinkLabel, BorderLayout.CENTER);
return jPanel;
}
private static void showRPCDisconnectDialog() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(
DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"),
UIManager.getString("OptionPane.messageDialogTitle"),
JOptionPane.ERROR_MESSAGE,
UIManager.getIcon("OptionPane.errorIcon"));
EnvChangeEntrance.getInstance().chooseEnv();
}
});
}
private static boolean checkRPCConnect() {
CloseableHttpClient httpclient = HttpClients.createDefault();
WorkspaceConnectionInfo info = getConnectionInfo();
HttpGet httpGet = new HttpGet(StableUtils.pathJoin(info.getUrl(), WorkspaceConstants.CONTROLLER_PREFIX, WorkspaceConstants.VT));
RequestConfig requestConfig = RequestConfig
.custom()
.setConnectTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build();
httpGet.setConfig(requestConfig);
try {
CloseableHttpResponse response = httpclient.execute(httpGet);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
return false;
}
return true;
}
//配置变更监听器
private static final Emitter.Listener modifyConfig = new Emitter.Listener() {
@Override
@ -282,7 +349,7 @@ public class DesignerSocketIO {
private static void printLog(Object[] objects, PrintEventLog printEventLog, String prefix) {
for (Object object : objects) {
if (object instanceof Throwable) {
Throwable throwable = (Throwable) object;
Throwable throwable = (Throwable) object;
printEventLog.printThrowable(throwable);
} else {
printEventLog.print(prefix, object);
@ -292,7 +359,8 @@ public class DesignerSocketIO {
interface PrintEventLog {
void printThrowable(Throwable throwable);
void print(String s, Object ...object);
void print(String s, Object... object);
}
enum PrintEventLogImpl implements PrintEventLog {
@ -321,4 +389,4 @@ public class DesignerSocketIO {
};
}
}
}

26
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -51,6 +51,8 @@ import com.fr.design.mainframe.JForm;
import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.mainframe.WidgetToolBarPane;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.question.QuestionWindow;
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager;
import com.fr.design.mainframe.bbs.BBSGuestPane;
import com.fr.design.mainframe.bbs.UserInfoPane;
import com.fr.design.mainframe.form.FormECCompositeProvider;
@ -72,6 +74,10 @@ import com.fr.design.share.ui.generate.ShareGeneratePane;
import com.fr.design.update.actions.RecoverForDesigner;
import com.fr.design.update.push.DesignerPushUpdateManager;
import com.fr.design.widget.ui.btn.FormSubmitButtonDetailPane;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.general.GeneralContext;
import com.fr.general.xml.GeneralXMLTools;
import com.fr.js.EmailJavaScript;
@ -128,6 +134,7 @@ import java.util.List;
import java.util.Set;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.SwingWorker;
/**
* Created by juhaoyu on 2018/1/31.
@ -465,5 +472,24 @@ public class DesignerActivator extends Activator implements Prepare {
public void prepare() {
LoginAuthServer.getInstance().start();
ContentReplacerCenter.getInstance().register();
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
// 触发下cid 搜索
ProductNewsSearchManager.getInstance().getProductNewsList();
return null;
}
@Override
protected void done() {
QuestionWindow.getInstance().setVisible(true);
}
}.execute();
}
});
}
}

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/blue_bulb.svg

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="5.40283" y="12.9943" width="5.16667" height="1.20556" rx="0.602778" fill="#1D7ADC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5167 6.53611C11.5167 7.55647 11.0838 8.47574 10.3917 9.1203C10.3917 9.12032 10.3918 9.12035 10.3918 9.12038C10.093 9.39865 9.74589 9.62573 9.36443 9.78764V10.928H6.60888V9.78809C6.22677 9.62605 5.87911 9.39864 5.57993 9.11988C5.57994 9.11985 5.57996 9.11983 5.57998 9.1198C4.88819 8.47527 4.45556 7.55621 4.45556 6.53611C4.45556 4.58624 6.03624 3.00556 7.98611 3.00556C9.93598 3.00556 11.5167 4.58624 11.5167 6.53611ZM5.40332 9.64432C5.40267 9.65911 5.40234 9.67398 5.40234 9.68892V10.506C4.10652 9.66092 3.25 8.19854 3.25 6.53611C3.25 3.92043 5.37043 1.8 7.98611 1.8C10.6018 1.8 12.7222 3.92043 12.7222 6.53611C12.7222 8.1985 11.8657 9.66084 10.57 10.5059V11.2724C10.57 11.748 10.1845 12.1335 9.70888 12.1335H6.26443C5.78885 12.1335 5.40332 11.748 5.40332 11.2724V9.64432Z" fill="#1D7ADC"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bulb.svg

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="5.40283" y="12.9943" width="5.16667" height="1.20556" rx="0.602778" fill="#C2C2C2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5167 6.53611C11.5167 7.55647 11.0838 8.47574 10.3917 9.1203C10.3917 9.12032 10.3918 9.12035 10.3918 9.12038C10.093 9.39865 9.74589 9.62573 9.36443 9.78764V10.928H6.60888V9.78809C6.22677 9.62605 5.87911 9.39864 5.57993 9.11988C5.57994 9.11985 5.57996 9.11983 5.57998 9.1198C4.88819 8.47527 4.45556 7.55621 4.45556 6.53611C4.45556 4.58624 6.03624 3.00556 7.98611 3.00556C9.93598 3.00556 11.5167 4.58624 11.5167 6.53611ZM5.40332 9.64432C5.40267 9.65911 5.40234 9.67398 5.40234 9.68892V10.506C4.10652 9.66092 3.25 8.19854 3.25 6.53611C3.25 3.92043 5.37043 1.8 7.98611 1.8C10.6018 1.8 12.7222 3.92043 12.7222 6.53611C12.7222 8.1985 11.8657 9.66084 10.57 10.5059V11.2724C10.57 11.748 10.1845 12.1335 9.70888 12.1335H6.26443C5.78885 12.1335 5.40332 11.748 5.40332 11.2724V9.64432Z" fill="#C2C2C2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/clear.svg

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8" cy="8" r="8" fill="#DADADD"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.2998 4.70021C11.1176 4.51797 10.8221 4.51797 10.6399 4.70021L7.99997 7.3401L5.36011 4.70024C5.17787 4.518 4.88239 4.518 4.70015 4.70024C4.5179 4.88249 4.5179 5.17796 4.70015 5.36021L7.34001 8.00007L4.70016 10.6399C4.51792 10.8222 4.51792 11.1176 4.70016 11.2999C4.88241 11.4821 5.17788 11.4821 5.36013 11.2999L7.99997 8.66003L10.6398 11.2999C10.8221 11.4822 11.1176 11.4822 11.2998 11.2999C11.4821 11.1177 11.4821 10.8222 11.2998 10.6399L8.65994 8.00007L11.2998 5.36018C11.4821 5.17794 11.4821 4.88246 11.2998 4.70021Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 736 B

3
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/close.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.8492 2.94974C12.5758 2.67637 12.1326 2.67637 11.8592 2.94974L7.89937 6.90957L3.93959 2.94978C3.66622 2.67641 3.223 2.67641 2.94964 2.94978C2.67627 3.22315 2.67627 3.66636 2.94964 3.93973L6.90942 7.89952L2.94966 11.8593C2.67629 12.1326 2.67629 12.5759 2.94966 12.8492C3.22302 13.1226 3.66624 13.1226 3.93961 12.8492L7.89937 8.88946L11.8592 12.8493C12.1325 13.1226 12.5758 13.1226 12.8491 12.8493C13.1225 12.5759 13.1225 12.1327 12.8491 11.8593L8.88932 7.89952L12.8492 3.93969C13.1225 3.66632 13.1225 3.2231 12.8492 2.94974Z" fill="#AEAEAE"/>
</svg>

After

Width:  |  Height:  |  Size: 697 B

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group.svg

@ -0,0 +1,4 @@
<svg width="10" height="17" viewBox="0 0 10 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.18736 0C6.65515 0 7.81846 0.39723 8.70621 1.21669C9.5658 2.00658 10 3.09498 10 4.45996C10 5.48298 9.70553 6.38371 9.11981 7.15654C8.88023 7.44403 8.25107 8.04406 7.3133 8.87524C6.85572 9.27043 6.53305 9.65035 6.31538 10.042C6.04967 10.4917 5.92212 10.9866 5.92212 11.5577V12.0647L5.73843 12.2483H3.97502L3.79133 12.0647V11.5577C3.79133 10.8039 3.92919 10.1376 4.20533 9.56229C4.52788 8.87111 5.27169 8.01628 6.4682 6.95314C6.94413 6.47721 7.09597 6.31877 7.2041 6.17474C7.62189 5.65251 7.82513 5.11901 7.82513 4.54813C7.82513 3.72777 7.58683 3.0854 7.12675 2.62526C6.66719 2.14572 5.99692 1.91036 5.09919 1.91036C4.04615 1.91036 3.29 2.24245 2.7969 2.92025C2.33854 3.50361 2.10874 4.30268 2.10874 5.34166L1.92506 5.52535H0.183688L0 5.34166C0 3.73829 0.443367 2.46503 1.34828 1.51494C2.26686 0.504505 3.55106 0 5.18736 0Z" fill="white"/>
<path d="M4.85732 13.4242C5.29615 13.4242 5.66674 13.5624 5.95708 13.8527C6.23882 14.1345 6.38561 14.4919 6.38561 14.9084C6.38561 15.3529 6.23444 15.7119 5.92928 15.9916C5.62394 16.2715 5.26927 16.4146 4.85732 16.4146C4.44537 16.4146 4.0907 16.2715 3.7796 15.9861C3.48668 15.6932 3.35107 15.3419 3.35107 14.9084C3.35107 14.4706 3.48937 14.1185 3.7796 13.8527C4.07252 13.5598 4.42386 13.4242 4.85732 13.4242Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group_new.svg

@ -0,0 +1,4 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.9794 8.01574C32.1473 8.63412 31.1164 9 30 9C27.2386 9 25 6.76142 25 4C25 3.15756 25.2083 2.36378 25.5763 1.66737C23.2735 0.597339 20.7065 0 18 0C8.05887 0 0 8.05887 0 18C0 27.9411 8.05887 36 18 36C27.9411 36 36 27.9411 36 18C36 14.3065 34.8875 10.8728 32.9794 8.01574Z" fill="#419BF9"/>
<circle cx="30" cy="4" r="4" fill="#EB1D1F"/>
</svg>

After

Width:  |  Height:  |  Size: 489 B

3
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg

@ -0,0 +1,3 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="18" cy="18" r="18" fill="#419BF9"/>
</svg>

After

Width:  |  Height:  |  Size: 151 B

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/history_search.svg

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 8C2 11.3137 4.68629 14 8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8ZM8 1C4.13401 1 1 4.13401 1 8C1 11.866 4.13401 15 8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1Z" fill="#AEAEAE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 3.5C8.27614 3.5 8.5 3.72386 8.5 4V7.79289L10.8536 10.1464C11.0488 10.3417 11.0488 10.6583 10.8536 10.8536C10.6583 11.0488 10.3417 11.0488 10.1464 10.8536L7.5 8.20711V4C7.5 3.72386 7.72386 3.5 8 3.5Z" fill="#AEAEAE"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

3
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/hot_search.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.54759 15C6.54759 15 0.338939 13.6343 3.11391 6.8562C3.11391 6.8562 3.74391 7.6094 3.65729 7.97182C3.65729 7.97182 4.15114 6.26102 5.21706 5.23902C6.13231 4.36087 7.06226 1.89215 6.20459 1C6.20459 1 10.4527 1.89215 10.9256 6.35465C10.9256 6.35465 11.4689 4.93277 12.5846 4.79225C12.5846 4.79225 12.2416 5.57345 12.5846 6.74525C12.5846 6.74525 16.1035 12.7688 10.039 14.8047C10.039 14.8047 11.8569 12.7406 8.00166 9.1984C8.00166 9.1984 7.09271 11.0954 6.54916 11.7639C6.54759 11.7656 5.03121 13.4656 6.54759 15Z" fill="#EB1D1F"/>
</svg>

After

Width:  |  Height:  |  Size: 643 B

3
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/minimize.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.6998 8.7C2.31321 8.7 1.9998 8.3866 1.9998 8C1.9998 7.6134 2.3132 7.3 2.6998 7.3L13.2998 7.3C13.6864 7.3 13.9998 7.6134 13.9998 8C13.9998 8.3866 13.6864 8.7 13.2998 8.7L2.6998 8.7Z" fill="#AEAEAE"/>
</svg>

After

Width:  |  Height:  |  Size: 353 B

Loading…
Cancel
Save