diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index 958d1fa652..8301a0ca32 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/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(); } diff --git a/designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java b/designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java index 5956cc9e33..d9a1cf0c21 100644 --- a/designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java +++ b/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 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 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) { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java index ee9ee2ec06..c0239c8fad 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java +++ b/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 specialCharParam = EscapeSqlHelperManager.getInstance().getSpecialCharParam(paras); + Set specialCharParam = EscapeSqlHelper.getInstance().getSpecialCharParam(paras); // 将参数转义等 Set 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 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 diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java index 77d3aa583a..b187a8bfa0 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java +++ b/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); diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java b/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java index a12ce0bcfc..a848b06d69 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java +++ b/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; + } } diff --git a/designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java b/designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java deleted file mode 100644 index cf98501c12..0000000000 --- a/designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java +++ /dev/null @@ -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()); - } - } -} diff --git a/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java b/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java index 29ed3a47e3..deda005c36 100644 --- a/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java +++ b/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(); - } - - } - } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/utils/LinkStrUtils.java b/designer-base/src/main/java/com/fr/design/utils/LinkStrUtils.java index d02c9abff2..b7f8217b44 100644 --- a/designer-base/src/main/java/com/fr/design/utils/LinkStrUtils.java +++ b/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(); diff --git a/designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java b/designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java index 070d63d850..37e01f788a 100644 --- a/designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java +++ b/designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java @@ -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 START_UP_COMPLETE_LISTENER = new Listener() { @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 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 terminateUnexpectedly() { + + Stream 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); } diff --git a/designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java b/designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java index be1036f0d8..4e4592dcde 100644 --- a/designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java +++ b/designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java @@ -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 = "
"; + + public static final String WEB_LIB_PATH = "%FR_HOME%\\webapps\\webroot\\WEB-INF\\lib:"; + + public static final String FR_HOME_LIB = "%FR_HOME%\\lib:"; } diff --git a/designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java b/designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java index fdfccf216f..b9253ed4cc 100644 --- a/designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java +++ b/designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java @@ -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> libMap) { + + String webLibPath = WEB_LIB_PATH; + String homeLibPath = FR_HOME_LIB; + + StringBuilder sb = new StringBuilder(); + + List homeLibs = libMap.get(homeLibPath); + if (!Collections.isEmpty(homeLibs)) { + sb.append(homeLibPath); + sb.append(StringUtils.join(homeLibs, SEPARATOR)); + } + + List 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(); } + } diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java b/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java index b13195067b..8cfc988a95 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java @@ -114,7 +114,11 @@ public class JarInconsistentDetector extends AbstractExceptionDetector { // 获取所有的不一致的 build List 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; } diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java b/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java index 8c85da202e..322c15d501 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java @@ -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 = "
"; - 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 lackInfos; + + // 远程 if (!WorkContext.getCurrent().isLocal()) { - return DetectorResult.normal(type()); + // 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包 + BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class); + // 远程情况 + List remoteInfos = buildInfoOperator.getBuildInfos(); + // 本地情况 + List localInfos = BuildInfoManager.getInstance().getInfos(); + + Set remoteSet = remoteInfos.stream() + .filter(this::isExistInfo) + .map(BuildInfo::getJar) + .collect(Collectors.toSet()); + + Predicate 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 buildInfos = buildInfoOperator.getBuildInfos(); + lackInfos = buildInfos.stream() + .filter(this::isLackInfo) + .collect(Collectors.toList()); } - - // 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包 - BuildInfoOperator buildInfoOperator = new BuildInfoOperatorImpl(); - List buildInfos = buildInfoOperator.getBuildInfos(); - List 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 infos) { - String webLibPath = WEB_LIB_PATH; - String homeLibPath = FR_HOME_LIB; - - Map> libMap = groupByPath(infos, homeLibPath, webLibPath); - - StringBuilder sb = new StringBuilder(); - - List homeLibs = libMap.get(homeLibPath); - if (!Collections.isEmpty(homeLibs)) { - sb.append(homeLibPath); - sb.append(StringUtils.join(homeLibs, SEPARATOR)); - } - - List 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> 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 diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java b/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java index ab2b16ed9a..57c97326e5 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java @@ -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, ClassNameConverter> throwableMap = new HashMap<>(); public ClassConflictConvertor() { @@ -83,6 +91,10 @@ public class ClassConflictConvertor implements ThrowableConverter { sign = sign.getCause(); } + Map> libMap = new HashMap<>(); + libMap.put(DetectorConstants.FR_HOME_LIB, new ArrayList<>()); + libMap.put(DetectorConstants.WEB_LIB_PATH, new ArrayList<>()); + Set 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 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, diff --git a/designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java b/designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java index 9b85c61af2..43a2f00b9d 100644 --- a/designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java +++ b/designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java @@ -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); } diff --git a/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java b/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java index 96120e317f..25689ad202 100644 --- a/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java +++ b/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java @@ -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() { @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 { + + + } } diff --git a/designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java b/designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java index ec77559856..ea3e72c3f5 100644 --- a/designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java +++ b/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() { diff --git a/designer-base/src/main/java/com/fr/exit/DesignerExiter.java b/designer-base/src/main/java/com/fr/exit/DesignerExiter.java index 3acb3cf8a9..babadc5fe8 100644 --- a/designer-base/src/main/java/com/fr/exit/DesignerExiter.java +++ b/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 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 results = EnvDetectorCenter.getInstance().terminate(throwable); + List 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 runAndGet(Supplier supplier, Supplier defaultCallable) { + + try { + return supplier.get(); + } catch (Exception ignore) { + return defaultCallable.get(); + } + } + } diff --git a/designer-base/src/main/resources/com/fr/design/standard/reminder/reminder_warning_window.svg b/designer-base/src/main/resources/com/fr/design/standard/reminder/reminder_warning_window.svg new file mode 100644 index 0000000000..66dde59232 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/standard/reminder/reminder_warning_window.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/designer-base/src/test/java/com/fr/design/components/notification/NotificationDialogTest.java b/designer-base/src/test/java/com/fr/design/components/notification/NotificationDialogTest.java index 1536dd2622..b4ae293979 100644 --- a/designer-base/src/test/java/com/fr/design/components/notification/NotificationDialogTest.java +++ b/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
3333", ""),new NotificationMessage.LinkMessage("display model2 test", "abc")); + }, new NotificationMessage.LinkMessage("1111 2222 33333333 4444 555 6666 66555 888 999 333
3333
444
555
", ""),new NotificationMessage.LinkMessage("display model2 test", "abc")); NotificationDialogProperties properties = new NotificationDialogProperties(frame, "test"); NotificationDialog dialog = new NotificationDialog(properties, Lists.newArrayList(model1, model2)); diff --git a/designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java b/designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java index 769707ebe5..eab2a64bb3 100644 --- a/designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java +++ b/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); + } + } diff --git a/designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java b/designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java new file mode 100644 index 0000000000..f8620f52d2 --- /dev/null +++ b/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)); + } +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java index d039b001df..9746c605d5 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java +++ b/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 { - 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这是一条测试数据"; + Style style0 = Style.DEFAULT_STYLE; + Assert.assertEquals(16, HtmlPaintUtils.deriveMaxFontFromRichChar(style0, testHtml0).getFRFont().getSize()); + + // 单元格字体size更大 + String testHtml1 = "这是一条测试数据"; + Style style1 = Style.DEFAULT_STYLE; + int oldFontSize = style1.getFRFont().getSize(); + Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style1, testHtml1).getFRFont().getSize()); + + // 富文本字体size更大 不同文本 有不同size + String testHtml2 = "这是一条测试数"; + 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 = "这是一条测试数据"; + Style style4 = Style.DEFAULT_STYLE; + oldFontSize = style1.getFRFont().getSize(); + Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style4, testHtml4).getFRFont().getSize()); + + + } + + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java index 1019281355..1d2a5eda26 100644 --- a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java +++ b/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); diff --git a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java index f95681be32..74654cd2ef 100644 --- a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java +++ b/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() { diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java index 9ceec2a2f8..8de2a0d637 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java +++ b/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"); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java index db89cf3482..b6819f56ca 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java +++ b/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)); diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java index 9ac98286e8..0518c6884f 100644 --- a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java +++ b/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")); diff --git a/designer-realize/src/main/java/com/fr/start/DesignerSubListener.java b/designer-realize/src/main/java/com/fr/start/DesignerSubListener.java index c76e6b0728..52d364f6cd 100644 --- a/designer-realize/src/main/java/com/fr/start/DesignerSubListener.java +++ b/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())); + }); } } }); diff --git a/designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java b/designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java index f5c9174649..ee4b265022 100644 --- a/designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java +++ b/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(); diff --git a/designer-realize/src/main/java/com/fr/start/FineDesigner.java b/designer-realize/src/main/java/com/fr/start/FineDesigner.java index a3e202308b..e70575708b 100644 --- a/designer-realize/src/main/java/com/fr/start/FineDesigner.java +++ b/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); + } + } } diff --git a/designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java b/designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java index 37f608ee16..92b8ac6c6f 100644 --- a/designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java +++ b/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 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 resultStream = DetectorBridge.getInstance().detect(fatal); + List 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 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() { diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java index 917de56f0d..4149753f72 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java +++ b/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) { diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg new file mode 100644 index 0000000000..16608753f1 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg new file mode 100644 index 0000000000..cabda1d9d9 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg @@ -0,0 +1,4 @@ + + + +