Browse Source

Merge remote-tracking branch 'origin/feature/x' into feature/x

feature/x
pengda 3 years ago
parent
commit
991d513eb4
  1. 2
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 66
      designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java
  3. 14
      designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java
  4. 18
      designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java
  5. 146
      designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java
  6. 30
      designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java
  7. 94
      designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java
  8. 8
      designer-base/src/main/java/com/fr/design/utils/LinkStrUtils.java
  9. 31
      designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java
  10. 7
      designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java
  11. 47
      designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java
  12. 11
      designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java
  13. 84
      designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java
  14. 36
      designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java
  15. 41
      designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java
  16. 66
      designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java
  17. 18
      designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java
  18. 66
      designer-base/src/main/java/com/fr/exit/DesignerExiter.java
  19. 9
      designer-base/src/main/resources/com/fr/design/standard/reminder/reminder_warning_window.svg
  20. 2
      designer-base/src/test/java/com/fr/design/components/notification/NotificationDialogTest.java
  21. 8
      designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java
  22. 42
      designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java
  23. 15
      designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java
  24. 49
      designer-form/src/test/java/com/fr/design/form/util/HtmlPaintUtilsTest.java
  25. 9
      designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java
  26. 4
      designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java
  27. 4
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java
  28. 59
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java
  29. 10
      designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java
  30. 6
      designer-realize/src/main/java/com/fr/start/DesignerSubListener.java
  31. 1
      designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java
  32. 20
      designer-realize/src/main/java/com/fr/start/FineDesigner.java
  33. 64
      designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java
  34. 40
      designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java
  35. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg
  36. 4
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg

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

@ -2240,7 +2240,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writer.attr("layoutTemplateStyle", this.getLayoutTemplateStyle());
writer.attr("showServerDatasetAuthTip", this.isShowServerDatasetAuthTip());
writer.attr("useOptimizedUPM4Adapter", this.isUseOptimizedUPM4Adapter());
writer.attr("propertiesUsable", false);
writer.attr("propertiesUsable", this.isPropertiesUsable());
writer.end();
}

66
designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java

@ -32,6 +32,7 @@ import java.awt.event.MouseEvent;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@ -43,8 +44,31 @@ import java.util.stream.Collectors;
**/
public class NotificationDialog extends JDialog {
private Dimension contentSize = new Dimension(300, 100);
private Dimension buttonDimension = new Dimension(68, 20);
/**
* 通知框的内部高度
*/
private static final int CONTENT_INNER_HEIGHT = 60;
/**
* 通知框如果出现滚动条后的内部宽度
*/
private static final int CONTENT_SCROLL_WIDTH = 280;
private static final int CONTENT_WIDTH = 300;
private static final int CONTENT_HEIGHT = 100;
/**
* 通知框的外部宽高
*/
private static final Dimension CONTENT_SIZE = new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT);
private static final Dimension BUTTON_DIMENSION = new Dimension(68, 20);
/**
* 标记 LABEL 没有作用
*/
private static final UILabel SIGN_LABEL = new UILabel("#");
/**
* 确认一个 LABEL 的宽高
*/
private static final Dimension SIGN_LABEL_DIMENSION = SIGN_LABEL.getPreferredSize();
private NotificationDialogProperties properties;
@ -138,7 +162,7 @@ public class NotificationDialog extends JDialog {
contentPanel.add(iconPanel, BorderLayout.WEST);
JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 20));
centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 5));
NotificationMessage[] messages = model.getMessages();
List<? extends JComponent> messageComponents = Arrays.stream(messages)
@ -151,18 +175,36 @@ public class NotificationDialog extends JDialog {
}
return new UILabel(LinkStrUtils.generateHtmlTag(messageModel.format()));
})
.collect(Collectors.toList());
// 当高度 大于 60 时,就会出现滚动条。
// 当出现滚动条时,需要将内部的宽度限制为 280, 否则会展示不出来
Function<Double, Integer> calStandardWidth = height -> height > CONTENT_INNER_HEIGHT ? CONTENT_SCROLL_WIDTH : CONTENT_WIDTH;
int widthUnit = messageComponents.stream()
.map((component) -> {
Dimension preferredSize = component.getPreferredSize();
double width = preferredSize.getWidth();
double widthFactor = Math.ceil(width / CONTENT_WIDTH);
// 这里的高度是没有限制宽度的,如果限制宽度,高度会变更,所以这里需要加上宽度的影响
return preferredSize.getHeight() + widthFactor * SIGN_LABEL_DIMENSION.getHeight();
})
.reduce(Double::sum)
.map(calStandardWidth)
.orElse(CONTENT_WIDTH);
messageComponents = messageComponents.stream()
.peek((component) -> {
Dimension preferredSize = component.getPreferredSize();
double componentWidth = preferredSize.getWidth();
double componentHeight = preferredSize.getHeight();
double widthFactor = Math.ceil(componentWidth / 300);
double heightFactor = Math.ceil(componentHeight / 15);
int realHeight = (int) (heightFactor + widthFactor - 1) * 15;
component.setPreferredSize(new Dimension(300, realHeight));
double heightFactor = Math.ceil(componentHeight / SIGN_LABEL_DIMENSION.getHeight());
double widthFactor = Math.ceil(componentWidth / widthUnit);
int realHeight = (int)Math.ceil(heightFactor + widthFactor - 1) * (int)(Math.ceil(SIGN_LABEL_DIMENSION.getHeight()));
component.setPreferredSize(new Dimension(widthUnit, realHeight));
})
.collect(Collectors.toList());
// 竖向排列
JPanel messageSummaryPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 0);
messageComponents.forEach(messageSummaryPanel::add);
@ -171,7 +213,7 @@ public class NotificationDialog extends JDialog {
jScrollPane.setBorder(BorderFactory.createEmptyBorder());
centerPanel.add(jScrollPane, BorderLayout.CENTER);
centerPanel.setPreferredSize(contentSize);
centerPanel.setPreferredSize(CONTENT_SIZE);
contentPanel.add(centerPanel, BorderLayout.CENTER);
@ -240,7 +282,7 @@ public class NotificationDialog extends JDialog {
NotificationAction action = currentModel.getAction();
if (action != null) {
UIButton actionButton = new UIButton(action.name());
actionButton.setPreferredSize(buttonDimension);
actionButton.setPreferredSize(BUTTON_DIMENSION);
actionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -251,7 +293,7 @@ public class NotificationDialog extends JDialog {
}
UIButton knowButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Know"));
knowButton.setPreferredSize(buttonDimension);
knowButton.setPreferredSize(BUTTON_DIMENSION);
knowButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {

14
designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java

@ -4,7 +4,7 @@ import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.base.ParameterMapNameSpace;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.escapesql.EscapeSqlHelperManager;
import com.fr.data.impl.EscapeSqlHelper;
import com.fr.data.operator.DataOperator;
import com.fr.decision.webservice.v10.config.ConfigService;
import com.fr.design.dialog.DialogActionAdapter;
@ -189,7 +189,7 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener {
Parameter[] paras = processParameters(tableData, calculator);
// 所有被转义参数的集合
refreshEscapeSqlHelper();
Set<String> specialCharParam = EscapeSqlHelperManager.getInstance().getSpecialCharParam(paras);
Set<String> specialCharParam = EscapeSqlHelper.getInstance().getSpecialCharParam(paras);
// 将参数转义等
Set<TableDataProvider> tableDataProviders = getTableDataProviders();
for (TableDataProvider provider : tableDataProviders) {
@ -228,10 +228,10 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener {
}
private static void refreshEscapeSqlHelper() {
EscapeSqlHelperManager.getInstance().setUseForbidWord(ConfigService.getInstance().getPSIConfig().isUseForbidWord());
EscapeSqlHelperManager.getInstance().setSelectedForbidWord(ConfigService.getInstance().getPSIConfig().getSelectedForbidWord());
EscapeSqlHelperManager.getInstance().setUseEscapeSpecialChar(ConfigService.getInstance().getPSIConfig().isUseEscapeSpecialChar());
EscapeSqlHelperManager.getInstance().setSelectedSpecialChar(ConfigService.getInstance().getPSIConfig().getSelectedSpecialChar());
EscapeSqlHelper.getInstance().setUseForbidWord(ConfigService.getInstance().getPSIConfig().isUseForbidWord());
EscapeSqlHelper.getInstance().setSelectedForbidWord(ConfigService.getInstance().getPSIConfig().getSelectedForbidWord());
EscapeSqlHelper.getInstance().setUseEscapeSpecialChar(ConfigService.getInstance().getPSIConfig().isUseEscapeSpecialChar());
EscapeSqlHelper.getInstance().setSelectedSpecialChar(ConfigService.getInstance().getPSIConfig().getSelectedSpecialChar());
}
private static boolean isShowSpecialCharSqlPane(List<int[]> specialCharParamIndex) {
@ -284,7 +284,7 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener {
if (classManagerProvider == null) {
return new HashSet<>();
}
return classManagerProvider.getArray(TableDataProvider.XML_TAG, EscapeSqlHelperManager.getInstance());
return classManagerProvider.getArray(TableDataProvider.XML_TAG, EscapeSqlHelper.getInstance());
}
@Override

18
designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java

@ -62,12 +62,8 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
UILabel buildWayLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Way") + " :");
buildWayPanel.add(buildWayLabel);
buildBox = new UIComboBox(buildWay);
buildBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
cardChanged(buildBox.getSelectedIndex());
}
buildBox.addItemListener(e -> {
cardChanged(buildBox.getSelectedIndex());
});
buildWayPanel.add(buildBox);
@ -79,7 +75,15 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
cardChanged(0);
}
private void cardChanged(int index) {
@Override
public void checkValid() throws Exception {
doBuildBoxSelect(buildBox.getSelectedIndex());
}
private void doBuildBoxSelect(Integer selectedIndex) {
}
private void cardChanged(int index) {
this.remove(controlPane);
this.remove(autoBuildPane);

146
designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java

@ -8,83 +8,89 @@ import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class TreeRootPane extends BasicPane {
// 是否支持多选(checkBoxTree)
//private JCheckBox multipleSelection;
private UICheckBox checkTypeCheckBox;
// richer:加载的方式,支持异步加载和完全加载
private UICheckBox loadTypeCheckBox;
private UICheckBox layerTypeCheckBox;
private UICheckBox returnFullPathCheckBox ;
public TreeRootPane() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JPanel checkTypePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
checkTypeCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Mutiple_Selection_Or_Not"));
checkTypeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
checkTypePane.add(checkTypeCheckBox);
this.add(checkTypePane);
JPanel loadTypePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
loadTypeCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Load_By_Async"));
loadTypeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
loadTypeCheckBox.addItemListener(e -> {
UICheckBox checkBox = (UICheckBox) e.getSource();
doLoadTypeChange(checkBox.isSelected());
});
loadTypePane.add(loadTypeCheckBox);
this.add(loadTypePane);
JPanel leafSelectPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
leafSelectPane.add(layerTypeCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Select_Leaf_Only")));
layerTypeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
this.add(leafSelectPane);
// 是否支持多选(checkBoxTree)
//private JCheckBox multipleSelection;
private UICheckBox checkTypeCheckBox;
// richer:加载的方式,支持异步加载和完全加载
private UICheckBox loadTypeCheckBox;
private UICheckBox layerTypeCheckBox;
private UICheckBox returnFullPathCheckBox;
public TreeRootPane() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JPanel checkTypePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
checkTypeCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Mutiple_Selection_Or_Not"));
checkTypeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
checkTypePane.add(checkTypeCheckBox);
this.add(checkTypePane);
JPanel loadTypePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
loadTypeCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Load_By_Async"));
loadTypeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
loadTypeCheckBox.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
UICheckBox checkBox = (UICheckBox) e.getSource();
doLoadTypeChange(checkBox.isSelected());
}
});
loadTypePane.add(loadTypeCheckBox);
this.add(loadTypePane);
JPanel leafSelectPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
leafSelectPane.add(layerTypeCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Select_Leaf_Only")));
layerTypeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
this.add(leafSelectPane);
JPanel returnFullPathPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
returnFullPathPane.add(returnFullPathCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Return_Full_Path")));
returnFullPathCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
this.add(returnFullPathPane);
}
private void doLoadTypeChange(boolean selected) {
//给埋点插件提供一个方法,埋埋点用
}
@Override
protected String title4PopupWindow() {
return "tree";
}
public void populate(TreeAttr treeAttr) {
checkTypeCheckBox.setSelected(treeAttr.isMultipleSelection());
loadTypeCheckBox.setSelected(treeAttr.isAjax());
layerTypeCheckBox.setSelected(treeAttr.isSelectLeafOnly());
checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
returnFullPathPane.add(returnFullPathCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Return_Full_Path")));
returnFullPathCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
this.add(returnFullPathPane);
}
private void doLoadTypeChange(Boolean selected) {
//给埋点插件提供一个方法,埋埋点用
}
@Override
protected String title4PopupWindow() {
return "tree";
}
public void populate(TreeAttr treeAttr) {
checkTypeCheckBox.setSelected(treeAttr.isMultipleSelection());
loadTypeCheckBox.setSelected(treeAttr.isAjax());
layerTypeCheckBox.setSelected(treeAttr.isSelectLeafOnly());
returnFullPathCheckBox.setSelected(treeAttr.isReturnFullPath());
}
}
public TreeAttr update() {
TreeAttr treeAttr = new TreeAttr();
treeAttr.setMultipleSelection(checkTypeCheckBox.isSelected());
treeAttr.setAjax(loadTypeCheckBox.isSelected());
treeAttr.setSelectLeafOnly(layerTypeCheckBox.isSelected());
public TreeAttr update() {
TreeAttr treeAttr = new TreeAttr();
treeAttr.setMultipleSelection(checkTypeCheckBox.isSelected());
treeAttr.setAjax(loadTypeCheckBox.isSelected());
treeAttr.setSelectLeafOnly(layerTypeCheckBox.isSelected());
treeAttr.setReturnFullPath(returnFullPathCheckBox.isSelected());
return treeAttr;
}
return treeAttr;
}
}

30
designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java

@ -1,30 +0,0 @@
package com.fr.design.update.actions;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import com.fr.log.FineLoggerFactory;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
/**
* 帮助-更新升级
* 点击查看新特性
* */
public class NewFeatureAction implements ActionListener {
private String url = CloudCenter.getInstance().acquireConf("fr.latest.update.detail", "https://help.fanruan.com/finereport/doc-view-4699.html");
@Override
public void actionPerformed(ActionEvent e) {
try {
BrowseUtils.browser(url);
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage());
}
}
}

94
designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java

@ -9,7 +9,6 @@ import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
@ -17,7 +16,6 @@ import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.update.actions.FileProcess;
import com.fr.design.update.actions.NewFeatureAction;
import com.fr.design.update.domain.UpdateInfoCachePropertyManager;
import com.fr.design.update.utils.UpdateFileUtils;
import com.fr.design.update.ui.widget.LoadingLabel;
@ -59,6 +57,7 @@ import java.util.*;
import java.util.List;
import java.util.concurrent.ExecutionException;
import static com.fr.design.dialog.FineJOptionPane.OPTION_OK_CANCEL;
import static java.nio.charset.StandardCharsets.*;
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
@ -186,7 +185,7 @@ public class UpdateMainDialog extends UIDialog {
double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED};
double[] columnUpdateContentPaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED};
double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE};
double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED};
double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED};
double[] columnUpdateSubContentPaneLabelSize = {UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE, TableLayout.PREFERRED};
JPanel jarUpdateContentPane = new JPanel();
@ -197,8 +196,7 @@ public class UpdateMainDialog extends UIDialog {
new Component[]{new UILabel(), new UILabel(), new UILabel()},
new Component[]{new UILabel(), updateVersionReminderPane, new UILabel()},
new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_JAR_Version")), jarCurrentLabel), new UILabel()},
new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Latest_JAR")), loadingLabel),
getNewFeatureActionLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Latest_Feature_Detail"))},
new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Latest_JAR")), loadingLabel), new UILabel()},
new Component[]{new UILabel(), new UILabel(), new UILabel()}
}, rowUpdateSubContentPaneSize, columnUpdateSubContentPaneSize, LayoutConstants.VGAP_LARGE);
jarUpdateContentPane2.setBackground(Color.WHITE);
@ -419,8 +417,8 @@ public class UpdateMainDialog extends UIDialog {
if (downloadFileConfig == null) {
throw new Exception("network error.");
}
HttpGet get = new HttpGet(CloudCenter.getInstance().acquireUrlByKind("updatelog") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr());
httpClient = HttpToolbox.getHttpClient(CloudCenter.getInstance().acquireUrlByKind("updatelog") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr());
HttpGet get = new HttpGet(CloudCenter.getInstance().acquireUrlByKind("changelog10") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr());
httpClient = HttpToolbox.getHttpClient(CloudCenter.getInstance().acquireUrlByKind("changelog10") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr());
response = httpClient.execute(get);
String responseText = CommonIOUtils.inputStream2String(response.getEntity().getContent(),EncodeConstants.ENCODING_UTF_8).trim();
JSONArray array = JSONArray.create();
@ -610,7 +608,41 @@ public class UpdateMainDialog extends UIDialog {
* jar包更新按钮监听器
*/
private void addActionListenerForUpdateBtn() {
updateButton.addActionListener(new UpdateAction());
updateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")};
int a = JOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Information"),
Toolkit.i18nText("Fine-Design_Update_Info_Title"),JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, UIManager.getIcon("OptionPane.warningIcon"), option, 1);
if (a == 0) {
progressBar.setVisible(true);
progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message"));
UpdateCallBack callBack = new UpdateProgressCallBack(progressBar);
updateButton.setEnabled(false);
updateLabel.setVisible(false);
RestoreResultDialog.deletePreviousPropertyFile();
final String installLib = StableUtils.pathJoin(StableUtils.getInstallHome(), ProjectConstants.LOGS_NAME, UpdateConstants.INSTALL_LIB);
final JFrame frame = DesignerContext.getDesignerFrame();
final RestartHelper helper = new RestartHelper();
FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY);
new FileProcess(callBack) {
@Override
public void onDownloadSuccess() {
progressBar.setVisible(false);
deleteForDesignerUpdate(installLib);
helper.restartForUpdate(frame);
}
@Override
public void onDownloadFailed() {
progressBar.setVisible(false);
deleteForDesignerUpdate(installLib);
FineJOptionPane.showMessageDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Failed_Message"));
helper.restartForUpdate(frame);
}
}.execute();
}
}
});
}
private void deleteForDesignerUpdate(String installLib) {
@ -656,13 +688,6 @@ public class UpdateMainDialog extends UIDialog {
return false;
}
private ActionLabel getNewFeatureActionLabel(final String text){
ActionLabel actionLabel = new ActionLabel(text);
actionLabel.addActionListener(new NewFeatureAction());
return actionLabel;
}
/**
* 显示窗口
*/
@ -680,43 +705,4 @@ public class UpdateMainDialog extends UIDialog {
@Override
public void checkValid() throws Exception {
}
private class UpdateAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")};
int a = JOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Information"),
Toolkit.i18nText("Fine-Design_Update_Info_Title"),JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, UIManager.getIcon("OptionPane.warningIcon"), option, 1);
if (a == 0) {
progressBar.setVisible(true);
progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message"));
UpdateCallBack callBack = new UpdateProgressCallBack(progressBar);
updateButton.setEnabled(false);
updateLabel.setVisible(false);
RestoreResultDialog.deletePreviousPropertyFile();
final String installLib = StableUtils.pathJoin(StableUtils.getInstallHome(), ProjectConstants.LOGS_NAME, UpdateConstants.INSTALL_LIB);
final JFrame frame = DesignerContext.getDesignerFrame();
final RestartHelper helper = new RestartHelper();
FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY);
new FileProcess(callBack) {
@Override
public void onDownloadSuccess() {
progressBar.setVisible(false);
deleteForDesignerUpdate(installLib);
helper.restartForUpdate(frame);
}
@Override
public void onDownloadFailed() {
progressBar.setVisible(false);
deleteForDesignerUpdate(installLib);
FineJOptionPane.showMessageDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Failed_Message"));
helper.restartForUpdate(frame);
}
}.execute();
}
}
}
}

8
designer-base/src/main/java/com/fr/design/utils/LinkStrUtils.java

@ -3,6 +3,7 @@ package com.fr.design.utils;
import com.fr.design.gui.ilable.UILabel;
import com.fr.stable.StringUtils;
import javax.swing.JComponent;
import java.awt.Color;
import java.awt.Font;
@ -13,6 +14,13 @@ public class LinkStrUtils {
public static final UILabel LABEL = new UILabel();
public static UILabel generateLabel(String html, JComponent templateLabel) {
String style = generateStyle(templateLabel.getBackground(), templateLabel.getFont(), templateLabel.getForeground());
String fullHtml = generateHtmlTag(style, html);
return new UILabel(fullHtml);
}
public static String generateHtmlTag(String html) {
String defaultStyle = generateDefaultStyle();

31
designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java vendored

@ -18,6 +18,7 @@ import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.start.server.EmbedServerEvent;
import com.fr.task.Once;
import com.fr.update.delay.DelayHelper;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
@ -53,7 +54,6 @@ public class EnvDetectorCenter {
}
};
private final Listener<Null> START_UP_COMPLETE_LISTENER = new Listener<Null>() {
@Override
@ -72,6 +72,14 @@ public class EnvDetectorCenter {
}
};
private final Once launchOnce = new Once(() -> {
// 添加启动完成监听
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, START_UP_COMPLETE_LISTENER);
// 切换完成后的监听
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, AFTER_SWITCH_LISTENER);
});
private final AtomicReference<DetectorProcess> PROCESS = new AtomicReference<>();
public static EnvDetectorCenter getInstance() {
@ -96,6 +104,7 @@ public class EnvDetectorCenter {
// 默认是启动
PROCESS.set(DetectorProcess.DESIGN_LAUNCH);
launchOnce.run();
listen();
}
@ -186,15 +195,21 @@ public class EnvDetectorCenter {
.collect(Collectors.toList());
}
/**
* 预期外的终止
*
* @return 检测结果
*/
public List<DetectorResult> terminateUnexpectedly() {
Stream<DetectorResult> resultStream = DetectorBridge.getInstance().detect();
return resultStream
.filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION)
.collect(Collectors.toList());
}
private void listen() {
// 添加启动完成监听
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, START_UP_COMPLETE_LISTENER);
// 切换完成后的监听
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, AFTER_SWITCH_LISTENER);
// 内置服务器监听
EventDispatcher.listen(EmbedServerEvent.BeforeStart, BEFORE_START_LISTENER);
EventDispatcher.listen(EmbedServerEvent.AfterStart, AFTER_START_LISTENER);
@ -202,8 +217,6 @@ public class EnvDetectorCenter {
private void stopListen() {
EventDispatcher.stopListen(START_UP_COMPLETE_LISTENER);
EventDispatcher.stopListen(AFTER_SWITCH_LISTENER);
EventDispatcher.stopListen(BEFORE_START_LISTENER);
EventDispatcher.stopListen(AFTER_START_LISTENER);
}

7
designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java vendored

@ -8,4 +8,11 @@ public class DetectorConstants {
public static final String JAR_HELP_LINK = "https://help.fanruan.com/finereport/doc-view-4700.html?source=3";
public static final String FINE_DB_HELP_LINK = "https://help.fanruan.com/finereport/doc-view-4701.html?source=3";
public static final String SEPARATOR = "、";
public static final String BR_TAG = "<br/>";
public static final String WEB_LIB_PATH = "%FR_HOME%\\webapps\\webroot\\WEB-INF\\lib:";
public static final String FR_HOME_LIB = "%FR_HOME%\\lib:";
}

47
designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java vendored

@ -1,12 +1,12 @@
package com.fr.env.detect.base;
import com.fr.base.function.ThrowableRunnable;
import com.fr.common.util.Collections;
import com.fr.design.components.notification.NotificationAction;
import com.fr.design.components.notification.NotificationMessage;
import com.fr.design.components.notification.NotificationModel;
import com.fr.design.components.notification.NotificationType;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.utils.LinkStrUtils;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.ExceptionSolution;
@ -14,7 +14,7 @@ import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
import com.fr.env.detect.bean.SolutionAction;
import com.fr.general.build.BuildInfo;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.JComponent;
@ -22,9 +22,15 @@ import java.awt.Desktop;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import static com.fr.env.detect.base.DetectorConstants.BR_TAG;
import static com.fr.env.detect.base.DetectorConstants.FR_HOME_LIB;
import static com.fr.env.detect.base.DetectorConstants.SEPARATOR;
import static com.fr.env.detect.base.DetectorConstants.WEB_LIB_PATH;
/**
* created by Harrison on 2022/05/25
**/
@ -114,7 +120,7 @@ public class DetectorUtil {
* @param message 信息
* @return 组件
*/
public static JComponent convert2TextComponent(@NotNull Message message) {
public static JComponent convert2TextComponent(@NotNull Message message, JComponent template) {
if (message.getType() == Message.Type.LINK) {
Message.Link linkMsg = (Message.Link) message;
@ -122,6 +128,39 @@ public class DetectorUtil {
Desktop.getDesktop().browse(URI.create(linkMsg.getLink()));
}));
}
return new UILabel(LinkStrUtils.generateHtmlTag(message.get()));
return LinkStrUtils.generateLabel(message.get(), template);
}
/**
* lib 转化成合适的格式
* %FR_HOME%/lib
* %FR_HOME%/webapps/webroot/WEB-INF/lib
*
* @param libMap jar 路径, key为前缀
* @return 信息
*/
public static String concatLibFormatMsg(Map<String, List<String>> libMap) {
String webLibPath = WEB_LIB_PATH;
String homeLibPath = FR_HOME_LIB;
StringBuilder sb = new StringBuilder();
List<String> homeLibs = libMap.get(homeLibPath);
if (!Collections.isEmpty(homeLibs)) {
sb.append(homeLibPath);
sb.append(StringUtils.join(homeLibs, SEPARATOR));
}
List<String> webLibs = libMap.get(webLibPath);
if (!Collections.isEmpty(webLibs)) {
if (sb.length() != 0) {
sb.append(BR_TAG);
}
sb.append(webLibPath);
sb.append(StringUtils.join(webLibs, SEPARATOR));
}
return sb.toString();
}
}

11
designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java vendored

@ -114,7 +114,11 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
// 获取所有的不一致的 build
List<BuildInfo> inConsistentInfos = buildInfos.stream()
.filter((e) -> !StringUtils.equals(designerBuild.get(), e.getGroupBuild()))
.filter((e) -> {
// 不为空,且不相等
return StringUtils.isNotEmpty(e.getGroupBuild())
&& !StringUtils.equals(designerBuild.get(), e.getGroupBuild());
})
.collect(Collectors.toList());
// 没有直接返回
@ -141,7 +145,10 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
for (BuildInfo localInfo : localInfos) {
String jar = localInfo.getJar();
String groupContent = localInfo.getGroupBuild();
localMap.put(jar, groupContent);
// 不一致的 JAR 检测,忽视缺少的情况
if (StringUtils.isNotEmpty(groupContent)) {
localMap.put(jar, groupContent);
}
}
return localMap;
}

84
designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java vendored

@ -12,6 +12,7 @@ import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
import com.fr.general.build.BuildInfo;
import com.fr.general.build.BuildInfoManager;
import com.fr.general.build.BuildInfoOperator;
import com.fr.general.build.impl.BuildInfoOperatorImpl;
import com.fr.third.guava.collect.Lists;
@ -22,18 +23,18 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static com.fr.env.detect.base.DetectorConstants.FR_HOME_LIB;
import static com.fr.env.detect.base.DetectorConstants.WEB_LIB_PATH;
/**
* created by Harrison on 2022/05/24
**/
public class JarLackDetector extends AbstractExceptionDetector {
public static final String SEPARATOR = "、";
public static final String BR_TAG = "<br/>";
public static final String WEB_LIB_PATH = "%FR_HOME%\\webapps\\webroot\\WEB-INF\\lib:";
public static final String FR_HOME_LIB = "%FR_HOME%\\lib:";
public JarLackDetector() {
super(DetectorType.LACK_OF_JAR);
@ -42,17 +43,40 @@ public class JarLackDetector extends AbstractExceptionDetector {
@Override
public DetectorResult detect() {
// 不支持远程
List<BuildInfo> lackInfos;
// 远程
if (!WorkContext.getCurrent().isLocal()) {
return DetectorResult.normal(type());
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class);
// 远程情况
List<BuildInfo> remoteInfos = buildInfoOperator.getBuildInfos();
// 本地情况
List<BuildInfo> localInfos = BuildInfoManager.getInstance().getInfos();
Set<String> remoteSet = remoteInfos.stream()
.filter(this::isExistInfo)
.map(BuildInfo::getJar)
.collect(Collectors.toSet());
Predicate<BuildInfo> remoteNotContains = (e) -> !remoteSet.contains(e.getJar());
lackInfos = localInfos.stream()
.filter(this::isExistInfo)
// 不是设计器的 JAR
.filter((e) -> !DetectorUtil.isDesignerJar(e))
.filter(remoteNotContains)
.collect(Collectors.toList());
} else {
// 本地
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = new BuildInfoOperatorImpl();
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos();
lackInfos = buildInfos.stream()
.filter(this::isLackInfo)
.collect(Collectors.toList());
}
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = new BuildInfoOperatorImpl();
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos();
List<BuildInfo> lackInfos = buildInfos.stream()
.filter(this::isLackInfo)
.collect(Collectors.toList());
if (Collections.isEmpty(lackInfos)) {
return DetectorResult.normal(type());
@ -77,6 +101,11 @@ public class JarLackDetector extends AbstractExceptionDetector {
return ExceptionLog.create(Toolkit.i18nText(type().getLogLocale()) + message);
}
private boolean isExistInfo(BuildInfo e) {
return !isLackInfo(e);
}
private boolean isLackInfo(BuildInfo e) {
return StringUtils.isEmpty(e.getGroupBuild());
@ -84,33 +113,12 @@ public class JarLackDetector extends AbstractExceptionDetector {
private Message tipsMessage(List<BuildInfo> infos) {
String webLibPath = WEB_LIB_PATH;
String homeLibPath = FR_HOME_LIB;
Map<String, List<String>> libMap = groupByPath(infos, homeLibPath, webLibPath);
StringBuilder sb = new StringBuilder();
List<String> homeLibs = libMap.get(homeLibPath);
if (!Collections.isEmpty(homeLibs)) {
sb.append(homeLibPath);
sb.append(StringUtils.join(homeLibs, SEPARATOR));
}
List<String> webLibs = libMap.get(webLibPath);
if (!Collections.isEmpty(webLibs)) {
if (sb.length() != 0) {
sb.append(BR_TAG);
}
sb.append(webLibPath);
sb.append(StringUtils.join(webLibs, SEPARATOR));
}
String mainContent = sb.toString();
Map<String, List<String>> libMap = groupByPath(infos, FR_HOME_LIB, WEB_LIB_PATH);
String content = DetectorUtil.concatLibFormatMsg(libMap);
DetectorType type = this.type();
String header = Toolkit.i18nText(type.getTipsLocale());
return new Message.Simple(header + mainContent);
return new Message.Simple(header + content);
}
@NotNull

36
designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java vendored

@ -2,19 +2,22 @@ package com.fr.env.detect.impl.converter;
import com.fr.design.i18n.Toolkit;
import com.fr.env.detect.base.DetectorConstants;
import com.fr.env.detect.base.DetectorUtil;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.ExceptionLog;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.thowable.ThrowableConverter;
import com.fr.stable.EncodeConstants;
import com.fr.stable.resource.ResourceLoader;
import com.fr.third.org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.el.MethodNotFoundException;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@ -41,6 +44,11 @@ public class ClassConflictConvertor implements ThrowableConverter {
*/
private static final Pattern JAR_NAME_PATTERN = Pattern.compile("([\\w+-\\.]*\\.jar)");
private static final String WEB_INF_STRING = "WEB-INF";
private static final String JAR_URL_SUFFIX = ".jar!";
private static final String JAR_FILE_SUFFIX = ".jar";
private static final String FILE_URL_PREFIX = "file:";
private final Map<Class<?>, ClassNameConverter> throwableMap = new HashMap<>();
public ClassConflictConvertor() {
@ -83,6 +91,10 @@ public class ClassConflictConvertor implements ThrowableConverter {
sign = sign.getCause();
}
Map<String, List<String>> libMap = new HashMap<>();
libMap.put(DetectorConstants.FR_HOME_LIB, new ArrayList<>());
libMap.put(DetectorConstants.WEB_LIB_PATH, new ArrayList<>());
Set<String> allPath = new HashSet<>();
for (String className : classNames) {
String classFile = convertClass2Path(className);
@ -95,14 +107,18 @@ public class ClassConflictConvertor implements ThrowableConverter {
}
for (URL url : urlList) {
String file = url.getFile();
Matcher matcher = JAR_NAME_PATTERN.matcher(url.getFile());
if (matcher.find()) {
String jar = matcher.group();
allPath.add(jar);
} else {
boolean containsClasses = file.contains(CLASSES);
if (containsClasses) {
allPath.add(CLASSES);
String decodeFileStr = URLDecoder.decode(file, EncodeConstants.ENCODING_UTF_8);
if (decodeFileStr.contains(JAR_URL_SUFFIX)) {
String jarPath = decodeFileStr.substring(FILE_URL_PREFIX.length(), decodeFileStr.indexOf(JAR_URL_SUFFIX) + JAR_FILE_SUFFIX.length());
String jar = new File(jarPath).getName();
if (allPath.add(jar)) {
List<String> libPath;
if (file.contains(WEB_INF_STRING)) {
libPath = libMap.get(DetectorConstants.WEB_LIB_PATH);
} else {
libPath = libMap.get(DetectorConstants.FR_HOME_LIB);
}
libPath.add(jar);
}
}
}
@ -115,7 +131,7 @@ public class ClassConflictConvertor implements ThrowableConverter {
return null;
}
String msg = StringUtils.join(allPath, SEPARATOR);
String msg = DetectorUtil.concatLibFormatMsg(libMap);
DetectorType type = DetectorType.JAR_CONFLICT;
return DetectorResult.exception(type,

41
designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java vendored

@ -1,5 +1,6 @@
package com.fr.env.detect.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.RestartHelper;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
@ -47,36 +48,54 @@ public class DetectorErrorDialog extends JDialog implements ActionListener {
super(parent, true);
JPanel northPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
JPanel headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
headerPane.setLayout(new BorderLayout(15, 0));
UILabel iconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/standard/reminder/reminder_warning_window.svg"));
headerPane.add(iconLabel, BorderLayout.WEST);
JPanel messagePane = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true);
{
UILabel boldHeader = new UILabel(Toolkit.i18nText("Fine-Design_Error_Start_Apology_Message"));
Font font = FRFont.getInstance(boldHeader.getFont().getFontName(), Font.PLAIN, 16);
boldHeader.setFont(font);
messagePane.add(boldHeader);
UILabel description = new UILabel(Toolkit.i18nText("Fine-Design_Send_Report_To_Us"));
messagePane.add(description);
}
headerPane.add(messagePane, BorderLayout.CENTER);
UILabel boldHeader = new UILabel(Toolkit.i18nText("Fine-Design_Error_Start_Apology_Message"));
Font font = FRFont.getInstance(boldHeader.getFont().getFontName(), Font.BOLD, 20);
boldHeader.setFont(font);
messagePane.add(boldHeader);
UILabel description = new UILabel(Toolkit.i18nText("Fine-Design_Send_Report_To_Us"));
messagePane.add(description);
northPane.add(messagePane);
northPane.add(headerPane);
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
centerPane.setLayout(new BorderLayout(0, 5));
UILabel detailDesc = new UILabel(Toolkit.i18nText("Fine-Design_Problem_Detail_Message"));
centerPane.add(detailDesc, BorderLayout.NORTH);
JPanel detailPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
detailPanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 10, 10));
detailPanel.setLayout(new BorderLayout(0, 8));
for (DetectorResult result : results) {
JPanel detailItemPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
detailItemPanel.setLayout(new BorderLayout(0, 8));
ExceptionTips tips = result.getTips();
UILabel template = new UILabel();
template.setBackground(Color.white);
if (tips != null) {
Message tipsMsg = tips.getMessage();
detailPanel.add(DetectorUtil.convert2TextComponent(tipsMsg), BorderLayout.NORTH);
detailItemPanel.add(DetectorUtil.convert2TextComponent(tipsMsg, template), BorderLayout.NORTH);
}
ExceptionSolution solution = result.getSolution();
if (solution != null) {
Message solutionMsg = solution.getMessage();
detailPanel.add(DetectorUtil.convert2TextComponent(solutionMsg), BorderLayout.CENTER);
detailItemPanel.add(DetectorUtil.convert2TextComponent(solutionMsg, template), BorderLayout.CENTER);
}
detailPanel.add(detailItemPanel, BorderLayout.CENTER);
}
JScrollPane detailPanelWrapper = new JScrollPane(detailPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
@ -110,7 +129,7 @@ public class DetectorErrorDialog extends JDialog implements ActionListener {
this.add(northPane, BorderLayout.NORTH);
this.add(centerPane, BorderLayout.CENTER);
this.add(southPane, BorderLayout.SOUTH);
this.setSize(new Dimension(600, 500));
this.setSize(new Dimension(650, 500));
GUICoreUtils.centerWindow(this);
}

66
designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java vendored

@ -52,11 +52,15 @@ import java.util.stream.Stream;
public class EnvDetectorDialog extends JDialog {
private static final ImageIcon LOADING_ICON = getLoadingIcon();
public static final int TIMEOUT = 1000;
private static final int TIMEOUT = 1000;
private JPanel body;
private static final Color SUCCESS_COLOR = new Color(22, 193, 83);
private final JPanel body;
private final JPanel headerPanel;
private UIButton detectButton;
private JPanel resultSummaryPane;
private final TablePanel tablePanel;
@ -128,7 +132,7 @@ public class EnvDetectorDialog extends JDialog {
JPanel headerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
headerPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 12, 0));
UIButton detectButton = new UIButton(buttonStatus.getDesc()) {
this.detectButton = new UIButton(buttonStatus.getDesc()) {
@Override
public ButtonUI getUI() {
@ -152,7 +156,7 @@ public class EnvDetectorDialog extends JDialog {
detectButton.setForeground(Color.WHITE);
detectButton.addActionListener(event -> {
if (buttonStatus.isNotExecuting()) {
startDetecting(detectButton);
startDetecting();
} else {
stopDetecting(detectButton);
}
@ -165,7 +169,7 @@ public class EnvDetectorDialog extends JDialog {
return headerPanel;
}
private void startDetecting(UIButton detectButton) {
private void startDetecting() {
// 重新检测的时候需要处理一些逻辑
if (buttonStatus == EnvDetectorButtonStatus.A_NEW) {
@ -173,7 +177,7 @@ public class EnvDetectorDialog extends JDialog {
}
// 执行前
buttonStatus = buttonStatus.next();
UIUtil.invokeLaterIfNeeded(() -> detectButton.setText(buttonStatus.getDesc()));
UIUtil.invokeLaterIfNeeded(EnvDetectorDialog.this::refreshHeaderPanel);
detectWorker = new SwingWorker<Void, Void>() {
@Override
@ -218,7 +222,7 @@ public class EnvDetectorDialog extends JDialog {
if (buttonStatus.isExecuting()) {
// 执行结束
buttonStatus = EnvDetectorButtonStatus.A_NEW;
UIUtil.invokeLaterIfNeeded(() -> detectButton.setText(buttonStatus.getDesc()));
UIUtil.invokeLaterIfNeeded(EnvDetectorDialog.this::refreshHeaderPanel);
}
}
};
@ -251,6 +255,42 @@ public class EnvDetectorDialog extends JDialog {
});
}
private void updateHeaderPanel() {
// 刷新按钮
detectButton.setText(buttonStatus.getDesc());
if (buttonStatus == EnvDetectorButtonStatus.A_NEW) {
this.resultSummaryPane = new JPanel();
this.resultSummaryPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
this.resultSummaryPane.setLayout(new BorderLayout(5, 0));
Boolean success = model.getResults()
.map((e) -> {
if (e.getStatus() == DetectorStatus.NORMAL) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}).reduce((a, b) -> a && b)
.orElse(Boolean.FALSE);
if (success) {
resultSummaryPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Result_Label")), BorderLayout.WEST);
UILabel successLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Result_Success"));
successLabel.setForeground(SUCCESS_COLOR);
resultSummaryPane.add(successLabel, BorderLayout.CENTER);
} else {
resultSummaryPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Result_Label")), BorderLayout.WEST);
UILabel resultLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Result_Error"));
resultLabel.setForeground(Color.RED);
resultSummaryPane.add(resultLabel, BorderLayout.CENTER);
}
this.headerPanel.add(BorderLayout.CENTER, resultSummaryPane);
} else {
if (resultSummaryPane != null) {
this.headerPanel.remove(resultSummaryPane);
}
}
}
/* table */
@ -394,6 +434,13 @@ public class EnvDetectorDialog extends JDialog {
return tailPanel;
}
private void refreshHeaderPanel() {
updateHeaderPanel();
pack();
repaint();
}
private void refresh() {
updateTable(this.tablePanel);
@ -504,4 +551,9 @@ public class EnvDetectorDialog extends JDialog {
public abstract EnvDetectorButtonStatus next();
}
private class EnvDetectorHeaderPanel extends JPanel {
}
}

18
designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java

@ -10,6 +10,8 @@ import com.fr.workspace.WorkContext;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
@ -62,9 +64,9 @@ public class ConfigToPropMigrator {
initDirectory();
try (Connection c = DriverManager.getConnection(url);
FileOutputStream entityOut = new FileOutputStream(PropertiesConstants.ENTITY_PROP_PATH);
FileOutputStream classHelperOut = new FileOutputStream(PropertiesConstants.CLASS_NAME_PROP_PATH);
FileOutputStream xmlEntityOut = new FileOutputStream(PropertiesConstants.XML_ENTITY_PROP_PATH)) {
OutputStreamWriter xmlEntityOut = new OutputStreamWriter(new FileOutputStream(PropertiesConstants.XML_ENTITY_PROP_PATH), StandardCharsets.UTF_8);
OutputStreamWriter entityOut = new OutputStreamWriter(new FileOutputStream(PropertiesConstants.ENTITY_PROP_PATH), StandardCharsets.UTF_8);
OutputStreamWriter classHelperOut = new OutputStreamWriter(new FileOutputStream(PropertiesConstants.CLASS_NAME_PROP_PATH), StandardCharsets.UTF_8)) {
processClassOrEntity(c, new Properties(), SELECT_FOR_ENTITY, entityOut);
processClassOrEntity(c, new Properties(), SELECT_FOR_CLASSNAME, classHelperOut);
@ -84,7 +86,7 @@ public class ConfigToPropMigrator {
}
}
private void processClassOrEntity(Connection c, Properties map, String sql, FileOutputStream outputStream) throws SQLException, IOException {
private void processClassOrEntity(Connection c, Properties map, String sql, OutputStreamWriter writer) throws SQLException, IOException {
PreparedStatement query = c.prepareStatement(sql);
ResultSet resultSet = query.executeQuery();
while (resultSet.next()) {
@ -94,19 +96,19 @@ public class ConfigToPropMigrator {
map.setProperty(id, value);
}
}
map.store(outputStream, null);
map.store(writer, null);
}
private void processXmlEntity(Connection c, Properties map, FileOutputStream outputStream) throws SQLException, IOException {
private void processXmlEntity(Connection c, Properties map, OutputStreamWriter writer) throws SQLException, IOException {
PreparedStatement query = c.prepareStatement(SELECT_FOR_XML_ENTITY);
ResultSet resultSet = query.executeQuery();
while (resultSet.next()) {
String id = resultSet.getString(1);
Blob value = resultSet.getBlob(2);
byte[] bytes = value.getBytes(1L, (int) value.length());
map.setProperty(id, new String(bytes));
map.setProperty(id, new String(bytes, StandardCharsets.UTF_8));
}
map.store(outputStream, null);
map.store(writer, null);
}
public void deletePropertiesCache() {

66
designer-base/src/main/java/com/fr/exit/DesignerExiter.java

@ -17,7 +17,9 @@ import com.fr.log.FineLoggerFactory;
import com.fr.process.engine.core.FineProcessContext;
import com.fr.process.engine.core.FineProcessEngineEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
/**
* @author hades
@ -32,16 +34,43 @@ public class DesignerExiter {
return INSTANCE;
}
/**
* 预期外的退出
* 首先检测是否有检测到的异常如果没有则运行默认行为
*
* @param defaultAction 默认行为
*/
public void exitUnexpectedly(Runnable defaultAction) {
// 尝试进行检测
List<DetectorResult> results = runAndGet(() -> EnvDetectorCenter.getInstance().terminateUnexpectedly(), ArrayList::new);
try {
if (!Collections.isEmpty(results)) {
showNewExitDialog(results);
}
} finally {
// 正常的话上面会直接退出, system.exit(0)
// 只有异常,或者不命中,才会走到这里
defaultAction.run();
}
}
public void exit(Throwable throwable) {
FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable);
doThrowableAction(() -> {
FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable);
}, () -> {
throwable.printStackTrace(System.err);
});
StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.UNEXCEPTED_START_FAILED.getId(),
DesignerErrorMessage.UNEXCEPTED_START_FAILED.getMessage(),
throwable.getMessage());
doThrowableAction(() -> {
StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.UNEXCEPTED_START_FAILED.getId(),
DesignerErrorMessage.UNEXCEPTED_START_FAILED.getMessage(),
throwable.getMessage());
});
// 尝试进行检测
List<DetectorResult> results = EnvDetectorCenter.getInstance().terminate(throwable);
List<DetectorResult> results = runAndGet(() -> EnvDetectorCenter.getInstance().terminate(throwable), ArrayList::new);
if (Collections.isEmpty(results)) {
// 为空,则
@ -89,4 +118,31 @@ public class DesignerExiter {
private void beforeExit() {
DesignerWorkspaceGenerator.stop();
}
/* 忽视异常的调用方法 */
private void doThrowableAction(Runnable runnable) {
doThrowableAction(runnable, null);
}
private void doThrowableAction(Runnable runnable, Runnable defaultRunnable) {
try {
runnable.run();
} catch (Throwable ignore) {
if (defaultRunnable != null) {
defaultRunnable.run();
}
}
}
private <T> T runAndGet(Supplier<T> supplier, Supplier<T> defaultCallable) {
try {
return supplier.get();
} catch (Exception ignore) {
return defaultCallable.get();
}
}
}

9
designer-base/src/main/resources/com/fr/design/standard/reminder/reminder_warning_window.svg

@ -0,0 +1,9 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.70605 45C1.40405 45 0.0540464 42.646 1.70505 39.771L20.998 6.157C22.649 3.281 25.351 3.281 27.001 6.157L46.295 39.771C47.946 42.646 46.596 45 43.294 45H4.70605Z" fill="#FBB03B"/>
<mask id="mask0_1308_50594" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="1" y="4" width="46" height="41">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 45H47V4H1V45Z" fill="white"/>
</mask>
<g mask="url(#mask0_1308_50594)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 39H26V35H22V39ZM27 17L26 33H22L21 17H27Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 688 B

2
designer-base/src/test/java/com/fr/design/components/notification/NotificationDialogTest.java

@ -31,7 +31,7 @@ public class NotificationDialogTest {
public void run(Object... args) {
System.out.println("1111");
}
}, new NotificationMessage.LinkMessage("1111 2222 33333333 4444 555 6666 66555 888 999 333 <br/> 3333", ""),new NotificationMessage.LinkMessage("display <a href='#'>model2</a> test", "abc"));
}, new NotificationMessage.LinkMessage("1111 2222 33333333 4444 555 6666 66555 888 999 333 <br/> 3333 <br /> 444 <br/> 555 <br/>", ""),new NotificationMessage.LinkMessage("display <a href='#'>model2</a> test", "abc"));
NotificationDialogProperties properties = new NotificationDialogProperties(frame, "test");
NotificationDialog dialog = new NotificationDialog(properties, Lists.newArrayList(model1, model2));

8
designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java

@ -5,6 +5,7 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.fun.FormAdaptiveConfigUIProcessor;
import com.fr.stable.Constants;
import com.fr.stable.unit.PT;
import java.math.BigDecimal;
/**
@ -43,4 +44,11 @@ public class FontTransformUtil {
return value * (double) Constants.DEFAULT_FONT_PAINT_RESOLUTION / (double) getDesignerFontResolution();
}
public static int roundUp(double num) {
String numStr = Double.toString(num);
numStr = new BigDecimal(numStr).setScale(0, BigDecimal.ROUND_HALF_UP).toString();
return Integer.valueOf(numStr);
}
}

42
designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java

@ -0,0 +1,42 @@
package com.fr.design.form.util;
import com.fr.base.Style;
import com.fr.general.FRFont;
import com.fr.log.FineLoggerFactory;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 富文本导出工具栏
*
* @author hades
* @version 11.0
* Created by hades on 2022/5/19
*/
public class HtmlPaintUtils {
private static final Pattern FONT_SIZE_PATTERN = Pattern.compile(Pattern.quote("font-size:") + "(.*?)" + Pattern.quote("px"));
/**
* 设置单元格字体为富文本中的最大字体
*
* @param style
*/
public static Style deriveMaxFontFromRichChar(Style style, String html) {
int maxSize = style.getFRFont().getSize();
Matcher matcher = FONT_SIZE_PATTERN.matcher(html);
while (matcher.find()) {
String value = matcher.group(1);
try {
double pxSize = Double.parseDouble(value);
int ptSize = FontTransformUtil.roundUp(FontTransformUtil.px2pt(pxSize));
maxSize = Math.max(maxSize, ptSize);
} catch (Throwable e) {
FineLoggerFactory.getLogger().debug(e.getMessage(), e);
}
}
FRFont cellFont = style.getFRFont();
return style.deriveFRFont(cellFont.applySize(maxSize));
}
}

15
designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java

@ -14,6 +14,9 @@ import com.fr.form.ui.TreeEditor;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/*
@ -39,11 +42,13 @@ public class TreeEditorDefinePane extends CustomWritableRepeatEditorPane<TreeEdi
loadAsync = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Load_By_Async"));
loadAsync.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
loadAsync.addItemListener(e -> {
UICheckBox checkBox = (UICheckBox) e.getSource();
doLoadTypeChange(checkBox.isSelected());
loadAsync.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
UICheckBox checkBox = (UICheckBox) e.getSource();
doLoadTypeChange(checkBox.isSelected());
}
});
returnLeaf = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Return_Leaf"));
returnLeaf.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
@ -64,7 +69,7 @@ public class TreeEditorDefinePane extends CustomWritableRepeatEditorPane<TreeEdi
return panel;
}
private void doLoadTypeChange(boolean selected) {
private void doLoadTypeChange(Boolean selected) {
//给埋点插件提供一个方法,埋埋点用
}

49
designer-form/src/test/java/com/fr/design/form/util/HtmlPaintUtilsTest.java

@ -0,0 +1,49 @@
package com.fr.design.form.util;
import com.fr.base.Style;
import junit.framework.TestCase;
import org.junit.Assert;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/5/25
*/
public class HtmlPaintUtilsTest extends TestCase {
public void testDeriveMaxFontFromRichChar() {
// 富文本字体size更大
String testHtml0 = "<span style=\"font-size:21px;font-family:'宋体';\">这是一条测试数据</span>";
Style style0 = Style.DEFAULT_STYLE;
Assert.assertEquals(16, HtmlPaintUtils.deriveMaxFontFromRichChar(style0, testHtml0).getFRFont().getSize());
// 单元格字体size更大
String testHtml1 = "<span style=\"font-size:7px;font-family:'宋体';\">这是一条测试数据</span>";
Style style1 = Style.DEFAULT_STYLE;
int oldFontSize = style1.getFRFont().getSize();
Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style1, testHtml1).getFRFont().getSize());
// 富文本字体size更大 不同文本 有不同size
String testHtml2 = "<span style=\"font-size:21px;font-family:'宋体';\">这是一条测</span><span style=\"font-size:31px;font-family:'宋体';\">试数</span><span style=\"font-size:21px;font-family:'宋体';\">据</span>";
Style style2 = Style.DEFAULT_STYLE;
Assert.assertEquals(23, HtmlPaintUtils.deriveMaxFontFromRichChar(style2, testHtml2).getFRFont().getSize());
// 异常场景1
String testHtml3 = "xxxx奇怪的格式xxxx";
Style style3 = Style.DEFAULT_STYLE;
oldFontSize = style1.getFRFont().getSize();
Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style3, testHtml3).getFRFont().getSize());
// 异常场景2
String testHtml4 = "<span style=\"font-size:xxxxpx;font-family:'宋体';\">这是一条测试数据</span>";
Style style4 = Style.DEFAULT_STYLE;
oldFontSize = style1.getFRFont().getSize();
Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style4, testHtml4).getFRFont().getSize());
}
}

9
designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java

@ -1,5 +1,8 @@
package com.fr.design.cell.editor;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.GeneralUtils;
import com.fr.design.form.util.HtmlPaintUtils;
import java.awt.Component;
import javax.swing.SwingUtilities;
@ -42,6 +45,11 @@ public class RichTextCellEditor extends AbstractCellEditor implements
@Override
public void doOk() {
RichTextCellEditor.this.fireEditingStopped();
CellElement newCellElement = parentTplEC.getTemplateCellElement(cellElement.getColumn(), cellElement.getRow());
if (cellElement.getCellGUIAttr().isShowAsHTML()) {
newCellElement.setStyle(HtmlPaintUtils.deriveMaxFontFromRichChar(newCellElement.getStyle(), GeneralUtils.objectToString(newCellElement.getValue())));
DesignerContext.getDesignerFrame().refreshToolbar();
}
}
@Override
@ -49,7 +57,6 @@ public class RichTextCellEditor extends AbstractCellEditor implements
RichTextCellEditor.this.fireEditingCanceled();
}
});
richTextDialog.addDialogActionListener(this);
this.richTextPane.populate(parentTplEC, cellElement);
setShowAsHtml(cellElement);

4
designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java

@ -366,9 +366,7 @@ public class RichTextToolBar extends BasicPane {
};
private int roundUp(double num) {
String numStr = Double.toString(num);
numStr = new BigDecimal(numStr).setScale(0, BigDecimal.ROUND_HALF_UP).toString();
return Integer.valueOf(numStr);
return FontTransformUtil.roundUp(num);
}
private CaretListener textCareListener = new CaretListener() {

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

@ -191,7 +191,9 @@ public class AlphaFineConstants {
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 Icon YELLOW_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/yellow_bulb.svg");
public static final Icon LIGHT_YELLOW_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg");
public static final String HOT_SEARCH = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search");

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

@ -33,6 +33,7 @@ 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.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
@ -66,8 +67,11 @@ import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
/**
* @author hades
@ -241,13 +245,10 @@ public class AlphaFineFrame extends JFrame {
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);
@ -264,19 +265,63 @@ public class AlphaFineFrame extends JFrame {
private MouseAdapter tipMouseListener = new MouseAdapter() {
private JPopupMenu popupMenu;
@Override
public void mouseEntered(MouseEvent e) {
useTipLabel.setForeground(UIConstants.FLESH_BLUE);
tipIconLabel.setIcon(AlphaFineConstants.BLUE_BULB_ICON);
tipIconLabel.setIcon(AlphaFineConstants.YELLOW_BULB_ICON);
}
@Override
public void mouseExited(MouseEvent e) {
useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON);
if (popupMenu == null || !popupMenu.isShowing()) {
useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON);
}
}
@Override
public void mousePressed(MouseEvent e) {
useTipLabel.setForeground(UIConstants.FLESH_BLUE);
tipIconLabel.setIcon(AlphaFineConstants.LIGHT_YELLOW_BULB_ICON);
popupMenu = createTipPop();
GUICoreUtils.showPopupMenu(popupMenu, e.getComponent(), e.getComponent().getX() - 60, e.getComponent().getY() + 20);
}
};
private JPopupMenu createTipPop() {
JPanel panel = new JPanel(new BorderLayout());
String toolTip = AlphaFineShortCutUtil.getDisplayShortCut(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Short_Cut", DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getShortcuts()));
UILabel label = new UILabel(toolTip);
label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8);
label.setBackground(Color.WHITE);
panel.add(label);
panel.setBackground(Color.WHITE);
JPopupMenu popupMenu = new JPopupMenu();
popupMenu.setBorder(BorderFactory.createEmptyBorder(20, 5, 10, 5));
popupMenu.add(panel);
popupMenu.setBackground(Color.WHITE);
popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
// do nothing
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6);
tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON);
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
// do nothing
}
});
return popupMenu;
}
private JPanel createSearchPane() {
JPanel searchPane = new JPanel(new BorderLayout());
searchPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20));

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

@ -35,6 +35,7 @@ import com.fr.design.mainframe.share.ui.base.ui.PlaceHolderUI;
import com.fr.design.mainframe.share.util.ShareUIUtils;
import com.fr.design.share.effect.EffectItemGroup;
import com.fr.design.share.utils.ShareDialogUtils;
import com.fr.file.FileCommonUtils;
import com.fr.form.share.DefaultSharableWidget;
import com.fr.form.share.bean.StyleThemeBean;
import com.fr.form.share.constants.ShareComponentConstants;
@ -659,6 +660,15 @@ public class ShareMainPane extends JPanel {
Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"));
return false;
}
if (FileCommonUtils.isFileNameValid(name)) {
FineJOptionPane.showMessageDialog(
shareDialog,
Toolkit.i18nText("Fine-Design_Share_Generate_Failure_Illegal_Component_Name_Tip"),
Toolkit.i18nText("Fine-Design_Basic_Error"),
ERROR_MESSAGE,
UIManager.getIcon("OptionPane.errorIcon"));
return false;
}
if (upload && StringUtils.isEmpty(content.getText())) {
FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Content"),
Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"));

6
designer-realize/src/main/java/com/fr/start/DesignerSubListener.java

@ -4,6 +4,7 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.exit.DesignerExiter;
import com.fr.process.engine.core.CarryMessageEvent;
import com.fr.process.engine.core.FineProcessContext;
import com.fr.process.engine.core.FineProcessEngineEvent;
@ -31,7 +32,10 @@ public class DesignerSubListener {
@Override
public void on(Event event, Null param) {
if (DesignerContext.getDesignerFrame() == null || !DesignerContext.getDesignerFrame().isShowing()) {
FineProcessContext.getParentPipe().fire(new CarryMessageEvent(DesignerProcessType.INSTANCE.obtain()));
DesignerExiter.getInstance().exitUnexpectedly(() -> {
FineProcessContext.getParentPipe().fire(new CarryMessageEvent(DesignerProcessType.INSTANCE.obtain()));
});
}
}
});

1
designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java

@ -95,6 +95,7 @@ public class DesignerSuperListener {
public void run() {
cancel = true;
ProcessEventPipe pipe = process.getPipe();
// 确认设计器是否启动完成
pipe.fire(FineProcessEngineEvent.READY);
if (StringUtils.isNotEmpty(pipe.info())) {
frameReport();

20
designer-realize/src/main/java/com/fr/start/FineDesigner.java

@ -1,5 +1,7 @@
package com.fr.start;
import com.fr.exit.DesignerExiter;
import com.fr.process.engine.FineProcessUtils;
import com.fr.process.engine.core.FineProcessEntry;
/**
@ -10,5 +12,21 @@ import com.fr.process.engine.core.FineProcessEntry;
* Created by hades on 2020/3/24
*/
public class FineDesigner extends FineProcessEntry {
public static void main(String[] args) {
FineDesigner fineDesigner = new FineDesigner();
FineProcessUtils.run(fineDesigner, args);
}
@Override
public void run(String[] args) {
try {
super.run(args);
} catch (Throwable throwable) {
// 守护进程启动时,需要捕获异常。并且退出。
DesignerExiter.getInstance().exit(throwable);
}
}
}

64
designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java

@ -1,15 +1,19 @@
package com.fr.start;
import com.fr.common.report.ReportState;
import com.fr.common.util.Collections;
import com.fr.design.RestartHelper;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector;
import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage;
import com.fr.env.detect.base.DetectorBridge;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorStatus;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.ui.DetectorErrorDialog;
import com.fr.exit.DesignerExiter;
import com.fr.general.IOUtils;
import com.fr.io.utils.ResourceIOUtils;
@ -17,14 +21,19 @@ import com.fr.log.FineLoggerFactory;
import com.fr.process.engine.core.CarryMessageEvent;
import com.fr.process.engine.core.FineProcessContext;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.lifecycle.ErrorType;
import com.fr.stable.lifecycle.ErrorTypeHelper;
import com.fr.stable.lifecycle.FineLifecycleFatalError;
import com.fr.stable.project.ProjectConstants;
import javax.swing.JOptionPane;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author hades
@ -68,10 +77,30 @@ public class LifecycleFatalErrorHandler {
* 自检测
*/
SELF {
final EnumMap<DetectorType, String> solutionMap = new EnumMap<>(DetectorType.class);
{
solutionMap.put(DetectorType.FINE_DB_LOCKED, "Fine-Design_Error_Finedb_Dirty_Backup_Reset");
solutionMap.put(DetectorType.FINE_DB_PERMISSION, "Fine-Design_Error_Finedb_Permission_Backup_Reset");
solutionMap.put(DetectorType.FINE_DB_DIRTY, "Fine-Design_Error_Finedb_Dirty_Backup_Reset");
}
@Override
public void handle(FineLifecycleFatalError fatal) {
String showText = generateShowText(fatal);
Stream<DetectorResult> resultStream = DetectorBridge.getInstance().detect(fatal);
List<DetectorResult> results = resultStream
.filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION)
.collect(Collectors.toList());
String showText = generateShowText(results);
// 如果还是异常,说明并不是 DB 的异常,抛出预期外的错误
if (StringUtils.isEmpty(showText)) {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
DetectorErrorDialog errorDialog = new DetectorErrorDialog(designerFrame, results);
errorDialog.setVisible(true);
return;
}
StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.FINEDB_PROBLEM.getId(),
DesignerErrorMessage.FINEDB_PROBLEM.getMessage(),
@ -107,26 +136,23 @@ public class LifecycleFatalErrorHandler {
/**
* 生成展示信息
*
* @param fatal 异常
* @return 文本
*/
private String generateShowText(FineLifecycleFatalError fatal) {
// todo 其实这里的交互还是有问题, 为什么在锁住和没权限的场景下,要重置 FineDB 呢。
DetectorResult detectorResult = DetectorBridge.getInstance().detect(DetectorType.FINE_DB_LOCKED, fatal);
if (detectorResult.getStatus() == DetectorStatus.EXCEPTION) {
return Toolkit.i18nText("Fine-Design_Error_Finedb_Locked_Backup_Reset");
}
detectorResult = DetectorBridge.getInstance().detect(DetectorType.FINE_DB_PERMISSION, fatal);
if (detectorResult.getStatus() == DetectorStatus.EXCEPTION) {
return Toolkit.i18nText("Fine-Design_Error_Finedb_Permission_Backup_Reset");
}
detectorResult = DetectorBridge.getInstance().detect(DetectorType.FINE_DB_DIRTY, fatal);
if (detectorResult.getStatus() == DetectorStatus.EXCEPTION) {
return Toolkit.i18nText("Fine-Design_Error_Finedb_Dirty_Backup_Reset");
private String generateShowText(List<DetectorResult> results) {
String showText = StringUtils.EMPTY;
if (Collections.isEmpty(results)) {
showText = Toolkit.i18nText("Fine-Design_Error_Finedb_Backup_Reset");
} else {
for (DetectorResult result : results) {
DetectorType type = result.getType();
String solutionLocale = solutionMap.get(type);
if (StringUtils.isNotEmpty(solutionLocale)) {
showText = Toolkit.i18nText(solutionLocale);
break;
}
}
}
return Toolkit.i18nText("Fine-Design_Error_Finedb_Backup_Reset");
return showText;
}
private void afterBackupFailed() {

40
designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java

@ -158,26 +158,26 @@ public class DesignerStartup extends Activator {
private void registerDaoSelector() {
// 注入设计器db cache 是否可用
DaoSelectorFactory.registerDaoSelector(() -> false);
// DesignerWorkspaceInfo info = WorkspaceUtils.getWorkspaceInfo();
// if (info.getType() == DesignerWorkspaceType.Remote) {
// } else {
// String webInfPath = WorkspaceUtils.getWorkspaceInfo().getPath();
// String dbConfigPath = StableUtils.pathJoin(webInfPath, ProjectConstants.CONFIG_DIRECTORY,
// EncryptionConstants.PROPERTY_NAME);
// String entityPath = generatePath(webInfPath, PropertiesConstants.ENTITY_PROP);
// String xmlEntityPath = generatePath(webInfPath, PropertiesConstants.XML_ENTITY_PROP);
// String classNamePath = generatePath(webInfPath, PropertiesConstants.CLASS_NAME_PROP);
// // 校验 平台迁移文件/缓存文件
// boolean existPropCache = new File(entityPath).exists() && new File(xmlEntityPath).exists() && new File(classNamePath).exists();
// DaoSelectorFactory.registerDaoSelector(() -> DesignerEnvManager.getEnvManager().isPropertiesUsable()
// && OptimizeUtil.isOpen()
// && existPropCache
// // demo启动时 前后目录可能会不一致 造成读取缓存失败
// && !startupArgsValue.getValue().isDemo()
// && !new File(dbConfigPath).exists());
//
// }
DesignerWorkspaceInfo info = WorkspaceUtils.getWorkspaceInfo();
if (info.getType() == DesignerWorkspaceType.Remote) {
DaoSelectorFactory.registerDaoSelector(() -> false);
} else {
String webInfPath = WorkspaceUtils.getWorkspaceInfo().getPath();
String dbConfigPath = StableUtils.pathJoin(webInfPath, ProjectConstants.CONFIG_DIRECTORY,
EncryptionConstants.PROPERTY_NAME);
String entityPath = generatePath(webInfPath, PropertiesConstants.ENTITY_PROP);
String xmlEntityPath = generatePath(webInfPath, PropertiesConstants.XML_ENTITY_PROP);
String classNamePath = generatePath(webInfPath, PropertiesConstants.CLASS_NAME_PROP);
// 校验 平台迁移文件/缓存文件
boolean existPropCache = new File(entityPath).exists() && new File(xmlEntityPath).exists() && new File(classNamePath).exists();
DaoSelectorFactory.registerDaoSelector(() -> DesignerEnvManager.getEnvManager().isPropertiesUsable()
&& OptimizeUtil.isOpen()
&& existPropCache
// demo启动时 前后目录可能会不一致 造成读取缓存失败
&& !startupArgsValue.getValue().isDemo()
&& !new File(dbConfigPath).exists());
}
}
private String generatePath(String webInfPath, String name) {

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_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="#FBB03B" fill-opacity="0.7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.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.64432C5.40267 9.65911 5.40234 9.67398 5.40234 9.68892ZM7.22753 3.55733C7.34074 3.8092 7.22833 4.10516 6.97646 4.21837C6.22719 4.55514 5.67439 5.25006 5.53469 6.08273C5.489 6.35507 5.23119 6.5388 4.95885 6.49311C4.68652 6.44742 4.50278 6.18961 4.54847 5.91727C4.74465 4.74793 5.51914 3.77702 6.56649 3.30627C6.81836 3.19306 7.11432 3.30546 7.22753 3.55733ZM5.71997 7.5277C5.60631 7.27603 5.31015 7.16416 5.05848 7.27782C4.80682 7.39148 4.69494 7.68763 4.8086 7.9393C4.83113 7.98918 4.85479 8.03844 4.87955 8.08703C5.00491 8.33308 5.30599 8.43092 5.55204 8.30556C5.79809 8.1802 5.89593 7.87911 5.77057 7.63306C5.7529 7.59839 5.73603 7.56326 5.71997 7.5277Z" fill="#FBB03B" fill-opacity="0.7"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

4
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_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="#FBB03B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.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.64432C5.40267 9.65911 5.40234 9.67398 5.40234 9.68892ZM7.22753 3.55733C7.34074 3.8092 7.22833 4.10516 6.97646 4.21837C6.22719 4.55514 5.67439 5.25006 5.53469 6.08273C5.489 6.35507 5.23119 6.5388 4.95885 6.49311C4.68652 6.44742 4.50278 6.18961 4.54847 5.91727C4.74465 4.74793 5.51914 3.77702 6.56649 3.30627C6.81836 3.19306 7.11432 3.30546 7.22753 3.55733ZM5.71997 7.5277C5.60631 7.27603 5.31015 7.16416 5.05848 7.27782C4.80682 7.39148 4.69494 7.68763 4.8086 7.9393C4.83113 7.98918 4.85479 8.03844 4.87955 8.08703C5.00491 8.33308 5.30599 8.43092 5.55204 8.30556C5.79809 8.1802 5.89593 7.87911 5.77057 7.63306C5.7529 7.59839 5.73603 7.56326 5.71997 7.5277Z" fill="#FBB03B"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Loading…
Cancel
Save