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 1f8ef8541..3d3540883 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -144,6 +144,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { //记录当前激活码的在线激活状态. private int activeKeyStatus = -1; private boolean joinProductImprove = true; + + private boolean embedServerLazyStartup = false; //最近使用的颜色 private ColorSelectConfigManager configManager = new ColorSelectConfigManager(); /** @@ -717,6 +719,24 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { designerPushUpdateConfigManager.setAutoPushUpdateEnabled(autoPushUpdateEnabled); } + /** + * 内置服务器是否使用时启动 + * + * @return 结果 + */ + public boolean isEmbedServerLazyStartup() { + return embedServerLazyStartup; + } + + /** + * 设置内置服务器使用时启动 + * + * @param embedServerLazyStartup 使用时启动 + */ + public void setEmbedServerLazyStartup(boolean embedServerLazyStartup) { + this.embedServerLazyStartup = embedServerLazyStartup; + } + /** * 是否磁盘空间参数 * @@ -1604,6 +1624,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { if ((tmpVal = reader.getAttrAsString("recentSelectedConnection", null)) != null) { this.setRecentSelectedConnection(tmpVal); } + this.setEmbedServerLazyStartup(reader.getAttrAsBoolean("embedServerLazyStartup", false)); } private void readReportPaneAttributions(XMLableReader reader) { @@ -1848,6 +1869,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { if (this.isTemplateTreePaneExpanded()) { writer.attr("templateTreePaneExpanded", this.isTemplateTreePaneExpanded()); } + if (this.isEmbedServerLazyStartup()) { + writer.attr("embedServerLazyStartup", this.isEmbedServerLazyStartup()); + } writer.end(); } diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java index 968d395f4..27b246188 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java @@ -21,7 +21,6 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.iprogressbar.UIProgressBarUI; import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.gui.itextfield.UITextField; -import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; @@ -40,7 +39,6 @@ import com.fr.general.log.Log4jConfig; import com.fr.locale.InterProviderFactory; import com.fr.log.FineLoggerFactory; import com.fr.stable.Constants; -import com.fr.stable.StringUtils; import com.fr.third.apache.log4j.Level; import com.fr.transaction.Configurations; import com.fr.transaction.Worker; @@ -48,46 +46,18 @@ import com.fr.workspace.WorkContext; import com.fr.workspace.server.vcs.VcsOperator; import com.fr.workspace.server.vcs.git.config.GcConfig; -import javax.swing.BorderFactory; -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; -import javax.swing.BoxLayout; -import javax.swing.JPanel; -import javax.swing.JProgressBar; -import javax.swing.JDialog; - -import javax.swing.Timer; -import javax.swing.SwingWorker; -import javax.swing.UIManager; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dialog; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FlowLayout; - -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowEvent; - -import java.awt.event.WindowAdapter; +import javax.swing.*; +import javax.swing.event.*; +import java.awt.*; +import java.awt.event.*; import java.io.File; import java.text.DecimalFormat; import java.util.Locale; import java.util.Map; -import java.util.UUID; import java.util.concurrent.ExecutionException; +import static com.fr.design.i18n.Toolkit.i18nText; + /** * 选项对话框 * @@ -168,6 +138,7 @@ public class PreferencePane extends BasicPane { private UICheckBox useUniverseDBMCheckbox; private UICheckBox joinProductImproveCheckBox; private UICheckBox autoPushUpdateCheckBox; + private UICheckBox embedServerLazyStartupCheckBox; private UICheckBox vcsEnableCheckBox; private UICheckBox saveCommitCheckBox; @@ -183,7 +154,7 @@ public class PreferencePane extends BasicPane { private JPanel gcProgressBarPanel = new JPanel(); private JProgressBar gcProgressBar; private Timer gcProgressTimer; - private UIButton gcOkButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK")); + private UIButton gcOkButton = new UIButton(i18nText("Fine-Design_Report_OK")); public PreferencePane() { this.initComponents(); @@ -196,9 +167,9 @@ public class PreferencePane extends BasicPane { UITabbedPane jtabPane = new UITabbedPane(); JPanel generalPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); - jtabPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_General"), generalPane); + jtabPane.addTab(i18nText("Fine-Design_Basic_General"), generalPane); JPanel advancePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); - jtabPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Advanced"), advancePane); + jtabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), advancePane); contentPane.add(jtabPane, BorderLayout.NORTH); createFunctionPane(generalPane); @@ -219,31 +190,31 @@ public class PreferencePane extends BasicPane { createServerPane(advancePane); - JPanel oraclePane = FRGUIPaneFactory.createTitledBorderPane("Oracle" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Oracle_All_Tables")); - oracleSpace = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Show_All_Oracle_Tables")); + JPanel oraclePane = FRGUIPaneFactory.createTitledBorderPane("Oracle" + i18nText("Fine-Design_Basic_Oracle_All_Tables")); + oracleSpace = new UICheckBox(i18nText("Fine-Design_Basic_Show_All_Oracle_Tables")); oraclePane.add(oracleSpace); - JPanel debuggerPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Basic_Develop_Tools")); - openDebugComboBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Open_Debug_Window")); + JPanel debuggerPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Develop_Tools")); + openDebugComboBox = new UICheckBox(i18nText("Fine-Design_Basic_Open_Debug_Window")); debuggerPane.add(openDebugComboBox, BorderLayout.CENTER); advancePane.add(debuggerPane); - JPanel upmSelectorPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager")); - useOptimizedUPMCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Use_New_Update_Plugin_Manager")); + JPanel upmSelectorPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Update_Plugin_Manager")); + useOptimizedUPMCheckbox = new UICheckBox(i18nText("Fine-Design_Basic_Use_New_Update_Plugin_Manager")); upmSelectorPane.add(useOptimizedUPMCheckbox); advancePane.add(upmSelectorPane); - JPanel dbmSelectorPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Manager")); - useUniverseDBMCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Use_Universe_Database_Manager")); + JPanel dbmSelectorPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Database_Manager")); + useUniverseDBMCheckbox = new UICheckBox(i18nText("Fine-Design_Basic_Use_Universe_Database_Manager")); dbmSelectorPane.add(useUniverseDBMCheckbox); advancePane.add(dbmSelectorPane); - JPanel improvePane = FRGUIPaneFactory.createVerticalTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Product_Improve")); - joinProductImproveCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Join_Product_Improve")); + JPanel improvePane = FRGUIPaneFactory.createVerticalTitledBorderPane(i18nText("Fine-Design_Basic_Product_Improve")); + joinProductImproveCheckBox = new UICheckBox(i18nText("Fine-Design_Basic_Join_Product_Improve")); improvePane.add(joinProductImproveCheckBox); if (DesignerPushUpdateManager.getInstance().isAutoPushUpdateSupported()) { - autoPushUpdateCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Automatic_Push_Update")); + autoPushUpdateCheckBox = new UICheckBox(i18nText("Fine-Design_Automatic_Push_Update")); improvePane.add(autoPushUpdateCheckBox); } @@ -252,15 +223,21 @@ public class PreferencePane extends BasicPane { spaceUpPane.add(createMemoryPane(), BorderLayout.CENTER); spaceUpPane.add(improvePane, BorderLayout.SOUTH); advancePane.add(spaceUpPane); + + JPanel embedServerPanel = FRGUIPaneFactory.createVerticalTitledBorderPane(i18nText("Fine-Design_Embed_Server")); + embedServerLazyStartupCheckBox = new UICheckBox(i18nText("Fine-Design_Startup_When_Needed")); + embedServerPanel.add(embedServerLazyStartupCheckBox); + advancePane.add(embedServerPanel); + } private void createVcsSettingPane(JPanel generalPane) { - JPanel vcsPane = FRGUIPaneFactory.createVerticalTitledBorderPane(Toolkit.i18nText("Fine-Design_Vcs_Title")); + JPanel vcsPane = FRGUIPaneFactory.createVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Title")); generalPane.add(vcsPane); - remindVcsLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Remind")); + remindVcsLabel = new UILabel(i18nText("Fine-Design_Vcs_Remind")); remindVcsLabel.setVisible(!VcsHelper.getInstance().needInit()); - vcsEnableCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Vcs_SaveAuto")); - saveCommitCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Vcs_No_Delete")); + vcsEnableCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_SaveAuto")); + saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete")); saveIntervalEditor = new IntegerEditor(60); useIntervalCheckBox = new UICheckBox(); @@ -271,8 +248,8 @@ public class PreferencePane extends BasicPane { enableVcsPanel.add(vcsEnableCheckBox); enableVcsPanel.add(remindVcsLabel); JPanel intervalPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout()); - final UILabel everyLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Every")); - final UILabel delayLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Delay")); + final UILabel everyLabel = new UILabel(i18nText("Fine-Design_Vcs_Every")); + final UILabel delayLabel = new UILabel(i18nText("Fine-Design_Vcs_Delay")); intervalPanel.add(useIntervalCheckBox); intervalPanel.add(everyLabel); intervalPanel.add(saveIntervalEditor); @@ -311,7 +288,7 @@ public class PreferencePane extends BasicPane { //gc面板 JPanel gcControlPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); JPanel gcButtonPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 40, 0)); - gcEnableCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Vcs_Storage_Optimization")); + gcEnableCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_Storage_Optimization")); gcButton = initGcButton(); gcButtonPane.add(gcButton); gcControlPane.add(gcEnableCheckBox); @@ -338,21 +315,22 @@ public class PreferencePane extends BasicPane { } private void createFunctionPane(JPanel generalPane) { - JPanel functionPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Function")); + JPanel functionPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Function")); generalPane.add(functionPane); //添加supportUndo选择项 - supportUndoCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Support_Undo")); + supportUndoCheckBox = new UICheckBox(i18nText("Fine-Design_Basic_Preference_Support_Undo")); functionPane.add(supportUndoCheckBox); //添加maxUndoLimit //String[] undoTimes = {"最大撤销次数","5次","10次","15次","20次","50次"}; - String[] undoTimes = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Max_Undo_Limit"), MAX_UNDO_LIMIT_5 + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_10 + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Time(s)") - , MAX_UNDO_LIMIT_15 + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_20 + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_50 + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Time(s)")}; + String[] undoTimes = {i18nText("Fine-Design_Basic_Max_Undo_Limit"), MAX_UNDO_LIMIT_5 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_10 + i18nText("Fine-Design_Basic_Time(s)") + , MAX_UNDO_LIMIT_15 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_20 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_50 + i18nText("Fine-Design_Basic_Time(s)")}; maxUndoLimit = new UIComboBox(undoTimes); functionPane.add(maxUndoLimit); //不支持撤销则不能选择撤销可缓存,也不能设置最大撤销次数 supportUndoCheckBox.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { maxUndoLimit.setEnabled(supportUndoCheckBox.isSelected()); } @@ -361,31 +339,32 @@ public class PreferencePane extends BasicPane { //添加supportDefaultParentCalculate选择项 supportDefaultParentCalculateCheckBox = new UICheckBox( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Support_Default_Parent_Calculate")); + i18nText("Fine-Design_Basic_Preference_Support_Default_Parent_Calculate")); functionPane.add(supportDefaultParentCalculateCheckBox); } private void createEditPane(JPanel generalPane) { //samuel:编辑器设置 - JPanel editPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Editor_Preference")); + JPanel editPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Editor_Preference")); generalPane.add(editPane); //设置是否支持将字符串编辑为公式 - supportStringToFormulaBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Support_String_To_Formula")); + supportStringToFormulaBox = new UICheckBox(i18nText("Fine-Design_Report_Support_String_To_Formula")); editPane.add(supportStringToFormulaBox); //是否默认转化 - defaultStringToFormulaBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Always")); + defaultStringToFormulaBox = new UICheckBox(i18nText("Fine-Design_Basic_Always")); editPane.add(defaultStringToFormulaBox); //不支持转化则不能默认执行 supportStringToFormulaBox.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { defaultStringToFormulaBox.setEnabled(supportStringToFormulaBox.isSelected()); } }); JPanel keyStrokePane = new JPanel(new BorderLayout()); - keyStrokePane.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Support_Auto_Complete_Shortcut") + ":"), BorderLayout.WEST); + keyStrokePane.add(new UILabel(i18nText("Fine-Design_Basic_Support_Auto_Complete_Shortcut") + ":"), BorderLayout.WEST); shortCutLabel = new UILabel(); keyStrokePane.add(shortCutLabel, BorderLayout.CENTER); editPane.add(keyStrokePane); @@ -415,7 +394,7 @@ public class PreferencePane extends BasicPane { requestFocusInWindow(); label = new UILabel(text); add(GUICoreUtils.createBorderLayoutPane( - new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Support_Current_Auto_Complete_Shortcut") + ":"), + new UILabel(i18nText("Fine-Design_Basic_Support_Current_Auto_Complete_Shortcut") + ":"), BorderLayout.WEST, label, BorderLayout.CENTER), @@ -449,24 +428,24 @@ public class PreferencePane extends BasicPane { private void createGuiOfGridPane(JPanel generalPane) { // GridPane - JPanel guiOfGridPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Setting_Grid")); + JPanel guiOfGridPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Setting_Grid")); generalPane.add(guiOfGridPane); - supportCellEditorDefCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Support_Cell_Editor_Definition")); + supportCellEditorDefCheckBox = new UICheckBox(i18nText("Fine-Design_Basic_Preference_Support_Cell_Editor_Definition")); guiOfGridPane.add(supportCellEditorDefCheckBox); - isDragPermitedCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Is_Drag_Permited")); + isDragPermitedCheckBox = new UICheckBox(i18nText("Fine-Design_Basic_Preference_Is_Drag_Permited")); guiOfGridPane.add(isDragPermitedCheckBox); } private void createColorSettingPane(JPanel generalPane) { // Color Setting Pane - JPanel colorSettingPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Setting_Colors")); + JPanel colorSettingPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Setting_Colors")); generalPane.add(colorSettingPane); - new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Grid_Line_Color")); + new UILabel(i18nText("Fine-Design_Basic_Preference_Grid_Line_Color")); - new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Pagination_Line_Color")); + new UILabel(i18nText("Fine-Design_Basic_Preference_Pagination_Line_Color")); gridLineColorTBButton = new UIColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png")); gridLineColorTBButton.setEnabled(this.isEnabled()); @@ -475,10 +454,10 @@ public class PreferencePane extends BasicPane { paginationLineColorTBButton.setEnabled(this.isEnabled()); JPanel leftPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); - leftPane.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Grid_Line_Color") + ":")); + leftPane.add(new UILabel(i18nText("Fine-Design_Basic_Preference_Grid_Line_Color") + ":")); leftPane.add(gridLineColorTBButton); JPanel rightPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); - rightPane.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Pagination_Line_Color") + ":")); + rightPane.add(new UILabel(i18nText("Fine-Design_Basic_Preference_Pagination_Line_Color") + ":")); rightPane.add(paginationLineColorTBButton); colorSettingPane.add(leftPane); colorSettingPane.add(rightPane); @@ -488,9 +467,9 @@ public class PreferencePane extends BasicPane { //richer:选择导出log文件的目录. JPanel logPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane(); advancePane.add(logPane); - JPanel logExportPane = FRGUIPaneFactory.createTitledBorderPane("log" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Export_Setting")); + JPanel logExportPane = FRGUIPaneFactory.createTitledBorderPane("log" + i18nText("Fine-Design_Basic_Export_Setting")); logPane.add(logExportPane); - UILabel logLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Select_Export_Log_Directory") + ":"); + UILabel logLabel = new UILabel(i18nText("Fine-Design_Basic_Select_Export_Log_Directory") + ":"); logExportPane.add(logLabel, BorderLayout.WEST); logExportDirectoryField = new UITextField(24); logExportPane.add(logExportDirectoryField, BorderLayout.CENTER); @@ -498,6 +477,7 @@ public class PreferencePane extends BasicPane { logExportPane.add(chooseDirBtn, BorderLayout.EAST); chooseDirBtn.setPreferredSize(new Dimension(25, 25)); chooseDirBtn.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent evt) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); @@ -509,11 +489,12 @@ public class PreferencePane extends BasicPane { } }); - JPanel logLevelPane = FRGUIPaneFactory.createTitledBorderPane("log" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Level_Setting")); + JPanel logLevelPane = FRGUIPaneFactory.createTitledBorderPane("log" + i18nText("Fine-Design_Basic_Level_Setting")); logPane.add(logLevelPane); logLevelComboBox = new UIComboBox(LOG); logLevelPane.add(logLevelComboBox); logLevelComboBox.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { Configurations.update(new Worker() { @Override @@ -533,13 +514,13 @@ public class PreferencePane extends BasicPane { private void createLanPane(JPanel generalPane) { // ben:选择版本语言; JPanel languageAndDashBoard_pane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane(); - JPanel LanguagePane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Choose_Language")); + JPanel LanguagePane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Choose_Language")); generalPane.add(languageAndDashBoard_pane); languageAndDashBoard_pane.add(LanguagePane); languageComboBox = createLanguageComboBox(); - ActionLabel languageLabel = new ActionLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Designer_Language")); + ActionLabel languageLabel = new ActionLabel(i18nText("Fine-Design_Basic_Designer_Language")); languageLabel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -553,7 +534,7 @@ public class PreferencePane extends BasicPane { dlg.setVisible(true); } }); - UILabel noticeLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Work_After_Restart_Designer"));//sail:提示重启后生效 + UILabel noticeLabel = new UILabel(i18nText("Fine-Design_Basic_Work_After_Restart_Designer"));//sail:提示重启后生效 double p = TableLayout.PREFERRED; double rowSize[] = {p}; double columnSize[] = {p, p, p}; @@ -599,16 +580,16 @@ public class PreferencePane extends BasicPane { double rowSize[] = {p}; // 长度单位选择 - JPanel lengthPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Setting_Ruler_Units")); + JPanel lengthPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Setting_Ruler_Units")); advancePane.add(lengthPane); - pageLengthComboBox = new UIComboBox(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Page_Setup_MM"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Unit_CM"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Unit_INCH")}); + pageLengthComboBox = new UIComboBox(new String[]{i18nText("Fine-Design_Basic_Page_Setup_MM"), i18nText("Fine-Design_Report_Unit_CM"), i18nText("Fine-Design_Report_Unit_INCH")}); pageLengthComboBox.setPreferredSize(new Dimension(80, 20)); pageLengthComboBox.setMinimumSize(new Dimension(80, 20)); - reportLengthComboBox = new UIComboBox(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Page_Setup_MM"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Unit_CM"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Unit_INCH"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Unit_PT_Duplicate")}); + reportLengthComboBox = new UIComboBox(new String[]{i18nText("Fine-Design_Basic_Page_Setup_MM"), i18nText("Fine-Design_Report_Unit_CM"), i18nText("Fine-Design_Report_Unit_INCH"), i18nText("Fine-Design_Report_Unit_PT_Duplicate")}); reportLengthComboBox.setPreferredSize(new Dimension(80, 20)); reportLengthComboBox.setMinimumSize(new Dimension(80, 20)); - UILabel pagelengthLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Page_Setup_Scale_Units") + ":"); - UILabel reportLengthLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Report_Design_Ruler_Units") + ":"); + UILabel pagelengthLabel = new UILabel(i18nText("Fine-Design_Basic_Page_Setup_Scale_Units") + ":"); + UILabel reportLengthLabel = new UILabel(i18nText("Fine-Design_Basic_Report_Design_Ruler_Units") + ":"); Component[][] lengthComponents = { {pagelengthLabel, pageLengthComboBox, reportLengthLabel, reportLengthComboBox}, }; @@ -621,13 +602,13 @@ public class PreferencePane extends BasicPane { double rowSize[] = {p}; double columnSize[] = {p, p, p}; - JPanel serverPortPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Port_Setting")); + JPanel serverPortPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Web_Preview_Port_Setting")); advancePane.add(serverPortPane); portEditor = new IntegerEditor(); portEditor.setPreferredSize(new Dimension(80, 20)); portEditor.setMinimumSize(new Dimension(80, 20)); - UILabel notiJlabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Work_After_Restart_Designer")); - UILabel serverPortLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Port") + ":"); + UILabel notiJlabel = new UILabel(i18nText("Fine-Design_Basic_Work_After_Restart_Designer")); + UILabel serverPortLabel = new UILabel(i18nText("Fine-Design_Basic_Web_Preview_Port") + ":"); Component[][] portComponents = { {serverPortLabel, portEditor, notiJlabel}, }; @@ -636,10 +617,10 @@ public class PreferencePane extends BasicPane { } private JPanel createMemoryPane() { - JPanel memoryPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Caching_Template")); - UILabel memoryLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Max_Caching_Template")); + JPanel memoryPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Caching_Template")); + UILabel memoryLabel = new UILabel(i18nText("Fine-Design_Basic_Preference_Max_Caching_Template")); UILabel memoryTipLabel = FRWidgetFactory.createLineWrapLabel( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Caching_Template_Tip"), MEMORY_TIP_LABEL_MAX_WIDTH); + i18nText("Fine-Design_Basic_Preference_Caching_Template_Tip"), MEMORY_TIP_LABEL_MAX_WIDTH); memoryTipLabel.setBorder(BorderFactory.createEmptyBorder(0, CACHING_GAP, 0, 0)); cachingTemplateSpinner = new UISpinner(0, CACHING_MAX, 1, CACHING_DEFAULT); JPanel memorySpace = new JPanel(FRGUIPaneFactory.createLeftZeroLayout()); @@ -652,7 +633,7 @@ public class PreferencePane extends BasicPane { @Override protected String title4PopupWindow() { - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_M_Window_Preference"); + return i18nText("Fine-Design_Basic_M_Window_Preference"); } /** @@ -734,6 +715,8 @@ public class PreferencePane extends BasicPane { if (this.autoPushUpdateCheckBox != null) { this.autoPushUpdateCheckBox.setSelected(designerEnvManager.isAutoPushUpdateEnabled()); } + + this.embedServerLazyStartupCheckBox.setSelected(designerEnvManager.isEmbedServerLazyStartup()); } private int chooseCase(int sign) { @@ -795,6 +778,7 @@ public class PreferencePane extends BasicPane { designerEnvManager.setOracleSystemSpace(this.oracleSpace.isSelected()); designerEnvManager.setCachingTemplateLimit((int) this.cachingTemplateSpinner.getValue()); designerEnvManager.setJoinProductImprove(this.joinProductImproveCheckBox.isSelected()); + designerEnvManager.setEmbedServerLazyStartup(this.embedServerLazyStartupCheckBox.isSelected()); VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager(); vcsConfigManager.setSaveInterval(this.saveIntervalEditor.getValue()); vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected()); @@ -842,7 +826,7 @@ public class PreferencePane extends BasicPane { @Override public Class[] targets() { - return new Class[] {ServerPreferenceConfig.class}; + return new Class[]{ServerPreferenceConfig.class}; } }); @@ -855,12 +839,12 @@ public class PreferencePane extends BasicPane { } int rv = JOptionPane.showOptionDialog( null, - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Language_Change_Successful"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), + i18nText("Fine-Design_Basic_Language_Change_Successful"), + i18nText("Fine-Design_Basic_Plugin_Warning"), JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, - new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer_Later")}, + new String[]{i18nText("Fine-Design_Basic_Restart_Designer"), i18nText("Fine-Design_Basic_Restart_Designer_Later")}, null ); if (rv == JOptionPane.OK_OPTION) { @@ -885,7 +869,7 @@ public class PreferencePane extends BasicPane { private void tryGc() { final SwingWorker worker = new SwingWorker() { - private long size = 0; + private long size = 0; @Override protected Boolean doInBackground() { @@ -898,12 +882,12 @@ public class PreferencePane extends BasicPane { try { get(); } catch (ExecutionException e) { - updateGcDialogPanelInfo(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Vcs_Need_Update_Remote_Server_Jar")); + updateGcDialogPanelInfo(i18nText("Fine-Design_Vcs_Need_Update_Remote_Server_Jar")); return; } catch (InterruptedException e) { FineLoggerFactory.getLogger().error(e, e.getMessage()); } - updateGcDialogPanelInfo(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Vcs_Reduce_File_Size") + fileSizeConvert(size)); + updateGcDialogPanelInfo(i18nText("Fine-Design_Vcs_Reduce_File_Size") + fileSizeConvert(size)); gcDialogDownPane.revalidate(); gcDialogDownPane.repaint(); gcDialogDownPane.add(gcOkButton); @@ -940,7 +924,7 @@ public class PreferencePane extends BasicPane { gcProgressBarPanel.remove(gcProgressBar); } if (null != gcDialog) { - gcDialog.setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Joption_News")); + gcDialog.setTitle(i18nText("Fine-Design_Form_Joption_News")); } } @@ -948,7 +932,7 @@ public class PreferencePane extends BasicPane { * 初始化 gc 对话框 */ private void initGcDialog() { - gcDialog = new JDialog((Dialog) SwingUtilities.getWindowAncestor(PreferencePane.this), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Vcs_Clean_Progress") + "...", true); + gcDialog = new JDialog((Dialog) SwingUtilities.getWindowAncestor(PreferencePane.this), i18nText("Fine-Design_Vcs_Clean_Progress") + "...", true); gcDialog.setSize(new Dimension(340, 140)); JPanel jp = new JPanel(); @@ -983,7 +967,7 @@ public class PreferencePane extends BasicPane { jp.setLayout(layout); //提示 - gcMessage = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Vcs_Cleaning")); + gcMessage = new UILabel(i18nText("Fine-Design_Vcs_Cleaning")); // 创建一个进度条 gcProgressBar = createGcProgressBar(0, 30, 240, 15, Color.GREEN); gcProgressTimer = createGcProgressTimer(500, gcProgressBar); @@ -1075,7 +1059,7 @@ public class PreferencePane extends BasicPane { * @return */ private UIButton initGcButton() { - UIButton gcButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Clean")); + UIButton gcButton = new UIButton(i18nText("Fine-Design_Vcs_Clean")); gcButton.setPreferredSize(new Dimension(100, 15)); gcButton.setRoundBorder(true, Constants.LEFT); return gcButton; diff --git a/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java b/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java index 9b7919933..4b532b92d 100644 --- a/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java +++ b/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java @@ -21,10 +21,15 @@ public enum DesignerLaunchStatus implements Event { */ DESIGNER_INIT_COMPLETE, + /** + * 打开模板完成 + */ + OPEN_LAST_FILE_COMPLETE, + /** * 启动完成 */ - OPEN_LAST_FILE_COMPLETE; + STARTUP_COMPLETE; private static DesignerLaunchStatus status; @@ -34,6 +39,6 @@ public enum DesignerLaunchStatus implements Event { public static void setStatus(DesignerLaunchStatus state) { status = state; - EventDispatcher.asyncFire(DesignerLaunchStatus.getStatus()); + EventDispatcher.fire(DesignerLaunchStatus.getStatus()); } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/UpdateActionManager.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/UpdateActionManager.java index 7f6ec1eb7..5a1b9de6c 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/UpdateActionManager.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/UpdateActionManager.java @@ -13,6 +13,8 @@ import com.fr.general.ComparatorUtils; import com.fr.general.GeneralUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.StableUtils; +import com.fr.value.NotNullLazyValue; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.HashMap; @@ -36,6 +38,22 @@ public class UpdateActionManager { private static boolean isRegisterIndexSearchTextTask = false; + private boolean afterStartup = false; + + private NotNullLazyValue isCacheValid = new NotNullLazyValue() { + @NotNull + @Override + protected Boolean compute() { + // 缓存是否有效。 + // 注意:开发工程版本为不是安装版本, + // 索引只会出现在首次启动。 + return ComparatorUtils.equals(GeneralUtils.readBuildNO(), AlphaFineConfigManager.getInstance().getCacheBuildNO()); + } + }; + + private ExecutorService searchPool = Executors + .newSingleThreadExecutor(new NamedThreadFactory("IndexAlphaFineSearchText", true)); + /** * 限制初始化 */ @@ -78,35 +96,27 @@ public class UpdateActionManager { * 1.首次索引或缓存失效的时候(更新版本会使缓存失效),会将索引缓存存到env.xml, * 下次直接加载。 * 2.需要重新索引,则等待设计器初始化完毕之后单线程运行索引任务。 + * 3.集中索引结束之后,每次添加为增量索引。 * * @param paneClass 面板类名 * @param updateAction 待处理的updateAction */ public void dealWithSearchText(String paneClass, UpdateAction updateAction) { Map actionSearchTextCache = AlphaFineConfigManager.getInstance().getActionSearchTextCache(); - if (!cacheValid() - || actionSearchTextCache.isEmpty() - || !actionSearchTextCache.containsKey(paneClass)) { - if (!updateActionsIndexCache.containsKey(paneClass)) { - updateActionsIndexCache.put(paneClass, updateAction); - } - registerIndexSearchTextTask(); - } else { + if (isCacheValid.getValue() && actionSearchTextCache.containsKey(paneClass)) { updateAction.setSearchText(actionSearchTextCache.get(paneClass)); + } else { + if (afterStartup) { + incrementIndexSearchTextTask(paneClass, updateAction); + } else { + if (!updateActionsIndexCache.containsKey(paneClass)) { + updateActionsIndexCache.put(paneClass, updateAction); + } + registerIndexSearchTextTask(); + } } } - /** - * 缓存是否有效。 - * 注意:开发工程版本为不是安装版本, - * 索引只会出现在首次启动。 - * - * @return true有效,false失效 - */ - private boolean cacheValid() { - return ComparatorUtils.equals(GeneralUtils.readBuildNO(), AlphaFineConfigManager.getInstance().getCacheBuildNO()); - } - /** * 由于是UI线程不考虑并发问题 */ @@ -116,26 +126,30 @@ public class UpdateActionManager { } isRegisterIndexSearchTextTask = true; // 没有缓存或者缓存失效的时候,等待设计器启动之后开始索引任务 - EventDispatcher.listen(DesignerLaunchStatus.OPEN_LAST_FILE_COMPLETE, new Listener() { + EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { @Override public void on(Event event, Null param) { - // 使用单线程索引 - ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("IndexAlphaFineSearchText")); + afterStartup = true; for (Map.Entry cache : updateActionsIndexCache.entrySet()) { - es.execute(new IndexTask(cache.getKey(), cache.getValue())); + searchPool.execute(new IndexTask(cache.getKey(), cache.getValue())); } - updateActionsIndexCache = null; - es.shutdown(); + updateActionsIndexCache.clear(); // 标记一下缓存版本 AlphaFineConfigManager.getInstance().setCacheBuildNO(GeneralUtils.readBuildNO()); } }); } + private void incrementIndexSearchTextTask(String key, UpdateAction action) { + searchPool.execute(new IndexTask(key, action)); + // 标记一下缓存版本 + AlphaFineConfigManager.getInstance().setCacheBuildNO(GeneralUtils.readBuildNO()); + } + /** * 索引任务 */ - class IndexTask implements Runnable { + static class IndexTask implements Runnable { private String className; private UpdateAction updateAction; diff --git a/designer-base/src/main/java/com/fr/design/ui/util/EdtInvocationManager.java b/designer-base/src/main/java/com/fr/design/ui/util/EdtInvocationManager.java new file mode 100644 index 000000000..321806821 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/util/EdtInvocationManager.java @@ -0,0 +1,49 @@ +package com.fr.design.ui.util; + +import org.jetbrains.annotations.NotNull; + +import javax.swing.SwingUtilities; +import java.lang.reflect.InvocationTargetException; + +/** + * 事件分发线程管理器。用于管理用户线程 + * + * @author vito + * @version 10.0 + * Created by vito on 2019/9/16 + */ +public abstract class EdtInvocationManager { + @NotNull + private static EdtInvocationManager ourInstance = new SwingEdtInvocationManager(); + + public abstract boolean isEventDispatchThread(); + + public abstract void invokeLater(@NotNull Runnable task); + + public abstract void invokeAndWait(@NotNull Runnable task) throws InvocationTargetException, InterruptedException; + + @NotNull + public static EdtInvocationManager getInstance() { + return ourInstance; + } + + /** + * The default {@link EdtInvocationManager} implementation which works with the EDT via SwingUtilities. + */ + private static class SwingEdtInvocationManager extends EdtInvocationManager { + @Override + public boolean isEventDispatchThread() { + return SwingUtilities.isEventDispatchThread(); + } + + @Override + public void invokeLater(@NotNull Runnable task) { + SwingUtilities.invokeLater(task); + } + + @Override + public void invokeAndWait(@NotNull Runnable task) throws InvocationTargetException, InterruptedException { + SwingUtilities.invokeAndWait(task); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/ui/util/GraphicsConfig.java b/designer-base/src/main/java/com/fr/design/ui/util/GraphicsConfig.java new file mode 100644 index 000000000..316b6ac24 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/util/GraphicsConfig.java @@ -0,0 +1,77 @@ +package com.fr.design.ui.util; + +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.Map; + +/** + * 图形渲染配置 + * + * @author vito + * @version 10.0 + * Created by vito on 2019/9/18 + */ +public class GraphicsConfig { + private final Graphics2D myG; + private final Map myHints; + private final Composite myComposite; + private final Stroke myStroke; + + public GraphicsConfig(@NotNull Graphics g) { + myG = (Graphics2D) g; + myHints = (Map) myG.getRenderingHints().clone(); + myComposite = myG.getComposite(); + myStroke = myG.getStroke(); + } + + public GraphicsConfig setAntialiasing(boolean on) { + myG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, on ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF); + return this; + } + + public GraphicsConfig setAlpha(float alpha) { + myG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); + return this; + } + + public GraphicsConfig setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { + myG.setRenderingHint(hintKey, hintValue); + return this; + } + + public Graphics2D getG() { + return myG; + } + + public GraphicsConfig setComposite(Composite composite) { + myG.setComposite(composite); + return this; + } + + public GraphicsConfig setStroke(Stroke stroke) { + myG.setStroke(stroke); + return this; + } + + public GraphicsConfig setupAAPainting() { + return setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) + .setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); + } + + public GraphicsConfig disableAAPainting() { + return setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF) + .setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT); + } + + public GraphicsConfig paintWithAlpha(float alpha) { + assert 0.0f <= alpha && alpha <= 1.0f : "alpha should be in range 0.0f .. 1.0f"; + return setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); + } + + public void restore() { + myG.setRenderingHints(myHints); + myG.setComposite(myComposite); + myG.setStroke(myStroke); + } +} diff --git a/designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java b/designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java new file mode 100644 index 000000000..b7583d0dd --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java @@ -0,0 +1,55 @@ +package com.fr.design.ui.util; + +import com.fr.log.FineLoggerFactory; +import org.jetbrains.annotations.NotNull; + +import javax.swing.SwingUtilities; + +/** + * 一些常用的 GUI 工具。 + *

+ * 为什么提供 invokeLaterIfNeeded 和 invokeAndWaitIfNeeded这样的方法? + * 因为 swing 渲染 UI 是单线程的,如果直接使用 + * {@link SwingUtilities#invokeLater(Runnable)},当 invokeLater 方法 + * 嵌套的时候,Runnable 会被放到事件循环队列的末尾,从而变成异步而非立即执行, + * 这是一处坑点。invokeLaterIfNeeded 的行为,当处于事件分发线程(EDT), + * 则直接运行,当处于其他线程,则使用 EDT 来执行。 + *

+ * 方法{@link SwingUtilities#invokeAndWait(Runnable)},也有一个注意点, + * 不允许在事件分发线程(EDT)中调用,否则抛错,所以也有必要加上判断 EDT 的逻辑。 + * + * @author vito + * @version 10.0 + * Created by vito on 2019/9/16 + */ +public class UIUtil { + /** + * 在 AWT 线程上立即调用runnable,否则使用 {@link SwingUtilities#invokeLater(Runnable)} 代替。 + * + * @param runnable 等待调用的 runnable + */ + public static void invokeLaterIfNeeded(@NotNull Runnable runnable) { + if (EdtInvocationManager.getInstance().isEventDispatchThread()) { + runnable.run(); + } else { + EdtInvocationManager.getInstance().invokeLater(runnable); + } + } + + /** + * 在 AWT 线程上立即调用runnable,否则使用 {@link SwingUtilities#invokeAndWait(Runnable)} 代替。 + * + * @param runnable 等待调用的 runnable + */ + public static void invokeAndWaitIfNeeded(@NotNull Runnable runnable) { + if (EdtInvocationManager.getInstance().isEventDispatchThread()) { + runnable.run(); + } else { + try { + EdtInvocationManager.getInstance().invokeAndWait(runnable); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } +} diff --git a/designer-base/src/main/java/com/fr/start/BaseDesigner.java b/designer-base/src/main/java/com/fr/start/BaseDesigner.java index 7bd6fbbd2..70399a2ac 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java @@ -13,6 +13,7 @@ import com.fr.design.fun.DesignerStartOpenFileProcessor; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.toolbar.ToolBarMenuDock; +import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.DesignUtils; import com.fr.event.Event; import com.fr.event.EventDispatcher; @@ -25,8 +26,7 @@ import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.OperatingSystem; -import javax.swing.SwingUtilities; -import java.awt.Window; +import java.awt.*; import java.io.File; import java.lang.reflect.Method; @@ -54,44 +54,33 @@ public abstract class BaseDesigner extends ToolBarMenuDock { } public void show() { - if (DesignerLaunchStatus.getStatus() == DesignerLaunchStatus.WORKSPACE_INIT_COMPLETE) { - refreshTemplateTree(); - } else { - EventDispatcher.listen(DesignerLaunchStatus.WORKSPACE_INIT_COMPLETE, new Listener() { - @Override - public void on(Event event, Null param) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - refreshTemplateTree(); - } - }); - } - }); - } + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + refreshTemplateTree(); + } + }); EventDispatcher.listen(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE, new Listener() { @Override public void on(Event event, Null param) { - SwingUtilities.invokeLater(new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { + // 打开上次的文件 showDesignerFrame(false); - DesignerContext.getDesignerFrame().resizeFrame(); - EventDispatcher.asyncFire(DesignerLaunchStatus.OPEN_LAST_FILE_COMPLETE); + DesignerLaunchStatus.setStatus(DesignerLaunchStatus.OPEN_LAST_FILE_COMPLETE); } }); } }); - EventDispatcher.listen(DesignerLaunchStatus.OPEN_LAST_FILE_COMPLETE, new Listener() { + EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { @Override public void on(Event event, Null param) { collectUserInformation(); } }); - // 启动界面 - DesignerContext.getDesignerFrame().setVisible(true); } private void refreshTemplateTree() { diff --git a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java index 0955c16e5..12aebd231 100644 --- a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java +++ b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java @@ -38,7 +38,7 @@ public class FineEmbedServerActivator extends Activator { } catch (LifecycleException e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); - }finally { + } finally { FineEmbedServerMonitor.getInstance().setComplete(); } } @@ -86,7 +86,7 @@ public class FineEmbedServerActivator extends Activator { private void stopSpring() { - AnnotationConfigWebApplicationContext context = ModuleRole.ServerRoot.getSingleton(AnnotationConfigWebApplicationContext.class); + AnnotationConfigWebApplicationContext context = ModuleRole.ServerRoot.findSingleton(AnnotationConfigWebApplicationContext.class); if (context != null) { context.stop(); context.destroy(); diff --git a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerMonitor.java b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerMonitor.java index 11514f0d3..078372183 100644 --- a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerMonitor.java +++ b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerMonitor.java @@ -36,7 +36,7 @@ public class FineEmbedServerMonitor { @Override public void on(Event event, Null aNull) { getInstance().reset(); - DesignerContext.getDesignerFrame().disposeProgressDialog(); + DesignerContext.getDesignerFrame().hideProgressDialog(); } }); } @@ -79,17 +79,15 @@ public class FineEmbedServerMonitor { scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { - while (!isComplete()) { - if (!DesignerContext.getDesignerFrame().getProgressDialog().isVisible()) { - DesignerContext.getDesignerFrame().showProgressDialog(); - DesignerContext.getDesignerFrame().getProgressDialog().updateLoadingText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Loading_Embed_Server")); - } - DesignerContext.getDesignerFrame().updateProgress(getProgress()); - try { - Thread.sleep(STEP_HEARTBEAT); - } catch (InterruptedException ignore) { - Thread.currentThread().interrupt(); - } + if (isComplete()) { + scheduler.shutdown(); + DesignerContext.getDesignerFrame().hideProgressDialog(); + return; + } + if (!DesignerContext.getDesignerFrame().getProgressDialog().isVisible()) { + DesignerContext.getDesignerFrame().showProgressDialog(); + DesignerContext.getDesignerFrame().getProgressDialog() + .updateLoadingText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Loading_Embed_Server")); } DesignerContext.getDesignerFrame().updateProgress(getProgress()); } diff --git a/designer-base/src/main/java/com/fr/start/server/ServerManageFrame.java b/designer-base/src/main/java/com/fr/start/server/ServerManageFrame.java index ff183b754..289a32426 100644 --- a/designer-base/src/main/java/com/fr/start/server/ServerManageFrame.java +++ b/designer-base/src/main/java/com/fr/start/server/ServerManageFrame.java @@ -5,18 +5,12 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.log.FineLoggerFactory; -import javax.swing.BorderFactory; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.SwingConstants; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; /** * 内置Tomcat服务器管理界面 @@ -46,7 +40,6 @@ public class ServerManageFrame extends JFrame { private ServerManageFrame() { - DesignUtils.initLookAndFeel(); this.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/trayStarted.png")); JPanel contentPane = (JPanel) this.getContentPane(); diff --git a/designer-chart/src/main/java/com/fr/design/chart/ChartDesignerActivator.java b/designer-chart/src/main/java/com/fr/design/chart/ChartDesignerActivator.java index 2034f4591..c3213c10b 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/ChartDesignerActivator.java +++ b/designer-chart/src/main/java/com/fr/design/chart/ChartDesignerActivator.java @@ -4,7 +4,6 @@ import com.fr.chart.chartattr.ChartCollection; import com.fr.design.ChartTypeInterfaceManager; import com.fr.design.actions.core.ActionFactory; import com.fr.design.chart.gui.ChartComponent; -import com.fr.design.constants.DesignerLaunchStatus; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.mainframe.ChartPropertyPane; import com.fr.design.module.ChartEmptyDataStyleAction; @@ -54,8 +53,6 @@ public class ChartDesignerActivator extends Activator implements Prepare { DesignImageEvent.registerDefaultCallbackEvent(HistoryTemplateListPane.getInstance()); DesignImageEvent.registerDownloadSourcesEvent(new DownloadOnlineSourcesHelper()); - DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE); - ChartTypeInterfaceManager.addPluginChangedListener(); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java index b13cdca85..ec425847d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java @@ -15,7 +15,7 @@ public class DesignerAppActivator extends Activator implements Prepare { @Override public void start() { - List appList = rightCollectMutable(App.KEY); + List appList = findMutable(App.KEY); for (App app : appList) { JTemplateFactory.register(app); } @@ -24,7 +24,7 @@ public class DesignerAppActivator extends Activator implements Prepare { @Override public void stop() { - List appList = rightCollectMutable(App.KEY); + List appList = findMutable(App.KEY); for (App app : appList) { JTemplateFactory.remove(app); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartupMessageCollector.java b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartupMessageCollector.java new file mode 100644 index 000000000..ac1072466 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartupMessageCollector.java @@ -0,0 +1,95 @@ +package com.fr.design.mainframe.messagecollect; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.SiteCenterToken; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; +import com.fr.general.CloudCenter; +import com.fr.general.ComparatorUtils; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.module.ModuleContext; +import com.fr.module.engine.FineModule; +import com.fr.runtime.FineRuntime; +import com.fr.stable.StringUtils; + +import java.util.HashMap; +import java.util.concurrent.ExecutorService; + +/** + * 启动信息收集 + * + * @author vito + * @version 10.0 + * Created by vito on 2019/9/4 + */ +public class StartupMessageCollector { + + private static final String XML_STARTUP_TIME = "t"; + private static final String XML_STARTUP_LOG = "startupLog"; + private static final String XML_STARTUP_Memory = "designerMemory"; + private static final String XML_STARTUP_COST = "cost"; + private static final String XML_UUID = "UUID"; + private static final String STARTUP_URL_KEY = "user.info.v10.startup"; + private static final String LOG_TYPE = "single"; + private static final int BYTE_TO_MB = 1024 * 1024; + + public static final StartupMessageCollector INSTANCE = new StartupMessageCollector(); + + private StartupMessageCollector() { + } + + public static StartupMessageCollector getInstance() { + return INSTANCE; + } + + public void recordStartupLog() { + EventDispatcher.listen(FineRuntime.ApplicationEvent.AFTER_START, new Listener() { + + @Override + public void on(Event event, Long param) { + final String url = CloudCenter.getInstance().acquireUrlByKind(STARTUP_URL_KEY); + if (StringUtils.isEmpty(url)) { + return; + } + ExecutorService es = ModuleContext.getExecutor() + .newSingleThreadExecutor(new NamedThreadFactory("StartupMessageCollector")); + es.submit(new Runnable() { + @Override + public void run() { + FineModule root = (FineModule) ModuleContext.getRoot().getRoot(); + JSONObject profile = root.profile(); + if (profile.isEmpty()) { + return; + } + JSONObject json = JSONObject.create() + .put(XML_UUID, DesignerEnvManager.getEnvManager().getUUID()) + .put(XML_STARTUP_TIME, FineRuntime.getAppStartTime() + FineRuntime.getStartingTime()) + .put(XML_STARTUP_COST, FineRuntime.getStartingTime()) + .put(XML_STARTUP_LOG, profile) + .put(XML_STARTUP_Memory, Runtime.getRuntime().totalMemory() / BYTE_TO_MB); + sendInfo(json, url + LOG_TYPE); + } + }); + es.shutdown(); + } + }); + } + + private boolean sendInfo(JSONObject content, String url) { + boolean success = false; + try { + HashMap para = new HashMap<>(); + para.put("token", SiteCenterToken.generateToken()); + para.put("content", content); + String res = HttpToolbox.post(url, para); + success = ComparatorUtils.equals(new JSONObject(res).get("status"), "success"); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return success; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java index 10a1ee0bd..e2b13b1ad 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java @@ -6,6 +6,7 @@ import com.fr.design.EnvChangeEntrance; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.loghandler.DesignerLogger; +import com.fr.design.ui.util.UIUtil; import com.fr.event.EventDispatcher; import com.fr.log.FineLoggerFactory; import com.fr.report.RemoteDesignConstants; @@ -22,9 +23,7 @@ import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; +import javax.swing.*; import java.io.IOException; import java.net.URI; import java.net.URL; @@ -88,7 +87,8 @@ public class DesignerSocketIO { */ if (status != Status.Disconnecting) { try { - SwingUtilities.invokeAndWait(new Runnable() { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override public void run() { JOptionPane.showMessageDialog( DesignerContext.getDesignerFrame(), diff --git a/designer-realize/src/main/java/com/fr/start/DesignerInitial.java b/designer-realize/src/main/java/com/fr/start/DesignerInitial.java index ea1faa321..dfbdb940d 100644 --- a/designer-realize/src/main/java/com/fr/start/DesignerInitial.java +++ b/designer-realize/src/main/java/com/fr/start/DesignerInitial.java @@ -1,24 +1,53 @@ package com.fr.start; +import com.fr.design.constants.DesignerLaunchStatus; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.ui.util.UIUtil; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; +import com.fr.event.Null; + /** * Created by juhaoyu on 2019-06-14. * 设计器上下文 */ public class DesignerInitial { - + private static volatile Designer designer; - - public synchronized static void init(String... args) { - - designer = new Designer(args); + + public static void init(final String... args) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + designer = new Designer(args); + } + }); } - - public synchronized static void show() { - - if (designer != null) { - designer.show(); - } - //启动画面结束 - SplashContext.getInstance().hide(); + + public static void prepare() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (designer != null) { + designer.show(); + } + } + }); + EventDispatcher.listen(DesignerLaunchStatus.OPEN_LAST_FILE_COMPLETE, new Listener() { + @Override + public void on(Event event, Null param) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + DesignerContext.getDesignerFrame().setVisible(true); + DesignerContext.getDesignerFrame().resizeFrame(); + //启动画面结束 + SplashContext.getInstance().hide(); + } + }); + DesignerLaunchStatus.setStatus(DesignerLaunchStatus.STARTUP_COMPLETE); + } + }); } } diff --git a/designer-realize/src/main/java/com/fr/start/SplashContext.java b/designer-realize/src/main/java/com/fr/start/SplashContext.java index e45eee48f..b437846b9 100644 --- a/designer-realize/src/main/java/com/fr/start/SplashContext.java +++ b/designer-realize/src/main/java/com/fr/start/SplashContext.java @@ -36,18 +36,19 @@ public class SplashContext { private SplashStrategy splashStrategy; - private String moduleID = ""; + private String moduleId = ""; private int loadingIndex = 0; private String[] loading = new String[]{"..", "....", "......"}; private int fetchOnlineTimes = 0; private String guest = StringUtils.EMPTY; + private boolean hasShowThanks = false; - private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("SplashContext")); + private ScheduledExecutorService scheduler = Executors + .newScheduledThreadPool(1, new NamedThreadFactory("SplashContext")); private Listener listener; - public static SplashContext getInstance() { return SPLASH_CONTEXT; } @@ -76,11 +77,11 @@ public class SplashContext { * 隐藏启动动画 */ public void hide() { - splashStrategy.hide(); - //取消监听 - EventDispatcher.stopListen(listener); // 窗口关闭后取消定时获取模块信息的timer scheduler.shutdown(); + //取消监听 + EventDispatcher.stopListen(listener); + splashStrategy.hide(); // 一次性 splashStrategy = null; } @@ -91,7 +92,7 @@ public class SplashContext { public void run() { showThanks(); loadingIndex++; - updateModuleLog(moduleID.isEmpty() ? StringUtils.EMPTY : moduleID + loading[loadingIndex % 3]); + updateModuleLog(moduleId.isEmpty() ? StringUtils.EMPTY : moduleId + loading[loadingIndex % 3]); } }, 0, 300, TimeUnit.MILLISECONDS); @@ -99,9 +100,9 @@ public class SplashContext { @Override public void on(Event event, String i18n) { - moduleID = i18n; + moduleId = i18n; loadingIndex++; - updateModuleLog(moduleID.isEmpty() ? StringUtils.EMPTY : moduleID + loading[loadingIndex % 3]); + updateModuleLog(moduleId.isEmpty() ? StringUtils.EMPTY : moduleId + loading[loadingIndex % 3]); } }; EventDispatcher.listen(ModuleEvent.MajorModuleStarting, listener); @@ -149,10 +150,11 @@ public class SplashContext { * 获取10次在线资源,最大时间3秒 */ private void showThanks() { - if (shouldShowThanks()) { + if (shouldShowThanks() && !hasShowThanks) { tryFetchOnline(); if (StringUtils.isNotEmpty(guest)) { updateThanksLog(THANKS + guest); + hasShowThanks = true; } } } diff --git a/designer-realize/src/main/java/com/fr/start/common/SplashCommon.java b/designer-realize/src/main/java/com/fr/start/common/SplashCommon.java new file mode 100644 index 000000000..916f4dfee --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/common/SplashCommon.java @@ -0,0 +1,66 @@ +package com.fr.start.common; + +import com.fr.design.ui.util.UIUtil; +import com.fr.start.SplashStrategy; + + +/** + * 静态启动画面 + * + * @author vito + * @version 10.0 + * Created by vito on 2019年9月16日 + */ +public class SplashCommon implements SplashStrategy { + + private SplashWindow splashWindow; + + @Override + public void show() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + splashWindow = new SplashWindow(); + splashWindow.setVisible(true); + } + }); + } + + @Override + public void hide() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (splashWindow != null) { + splashWindow.setVisible(false); + splashWindow.dispose(); + } + } + }); + + } + + @Override + public void updateModuleLog(final String text) { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + if (splashWindow != null) { + splashWindow.updateModuleLog(text); + } + } + }); + } + + @Override + public void updateThanksLog(final String text) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (splashWindow != null) { + splashWindow.updateThanksLog(text); + } + } + }); + } +} diff --git a/designer-realize/src/main/java/com/fr/start/common/SplashPane.java b/designer-realize/src/main/java/com/fr/start/common/SplashPane.java new file mode 100644 index 000000000..a96efe76f --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/common/SplashPane.java @@ -0,0 +1,120 @@ +package com.fr.start.common; + +import com.bulenkov.iconloader.IconLoader; +import com.bulenkov.iconloader.util.JBUI; +import com.fr.base.GraphHelper; +import com.fr.design.ui.util.GraphicsConfig; +import com.fr.stable.GraphDrawHelper; +import com.fr.stable.StringUtils; +import com.fr.stable.os.OperatingSystem; +import com.fr.value.NotNullLazyValue; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.util.Locale; + +/** + * 启动画面面板 + * + * @author vito + * @version 10.0 + * Created by vito on 2019/09/12 + */ +public class SplashPane extends JPanel { + + private static String OEM_PATH = "/com/fr/design/images/splash_10.png"; + private static float JBUI_INIT_SCALE = JBUI.scale(1f); + + private static final Color MODULE_COLOR = new Color(255, 255, 255); + private static final int MODULE_INFO_X = uiScale(36); + private static final int MODULE_INFO_Y = uiScale(339); + + private static final Color THANK_COLOR = new Color(255, 255, 255, (int) (0.6 * 255 + 0.5)); + private static final int THANK_INFO_X = uiScale(470); + private static final int FONT_SIZE = uiScale(12); + + private static final int MODULE_INFO_WIDTH = uiScale(150); + private static final int MODULE_INFO_HEIGHT = uiScale(20); + + private static final String ARIAL_FONT_NAME = "Arial"; + private static final String YAHEI_FONT_NAME = "Microsoft YaHei"; + + private String thanksLog = StringUtils.EMPTY; + private String moduleText = StringUtils.EMPTY; + + private static int uiScale(int i) { + return (int) (i * JBUI_INIT_SCALE); + } + + private NotNullLazyValue fontValue = new NotNullLazyValue() { + @NotNull + @Override + protected Font compute() { + Font font = null; + if (OperatingSystem.isWindows()) { + font = createFont(YAHEI_FONT_NAME); + } + if (font == null || isDialogFont(font)) { + font = createFont(ARIAL_FONT_NAME); + } + return font; + } + }; + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Icon icon = IconLoader.getIcon(OEM_PATH); + icon.paintIcon(null, g, 0, 0); + paintShowText((Graphics2D) g); + g.dispose(); + } + + + protected void paintShowText(Graphics2D g) { + GraphicsConfig config = new GraphicsConfig(g).setupAAPainting(); + + g.setPaint(MODULE_COLOR); + g.setFont(fontValue.getValue()); + + //加载模块信息 + GraphDrawHelper.drawString(g, moduleText, MODULE_INFO_X, MODULE_INFO_Y); + + //感谢用户信息 + if (StringUtils.isNotEmpty(thanksLog)) { + g.setPaint(THANK_COLOR); + GraphHelper.drawString(g, thanksLog, THANK_INFO_X, MODULE_INFO_Y); + } + config.restore(); + } + + Dimension getSplashDimension() { + Icon icon = IconLoader.getIcon(OEM_PATH); + return new Dimension(icon.getIconWidth(), icon.getIconHeight()); + } + + private boolean isDialogFont(Font font) { + return Font.DIALOG.equals(font.getFamily(Locale.US)); + } + + private Font createFont(String fontName) { + return new Font(fontName, Font.PLAIN, FONT_SIZE); + } + + /** + * 设置在启动过程中, 动态改变的文本, 如 当前启动的模块信息 + * + * @param text 指定的文本 + */ + void updateModuleLog(String text) { + moduleText = text; + repaint(MODULE_INFO_X, MODULE_INFO_Y - FONT_SIZE, MODULE_INFO_WIDTH, MODULE_INFO_HEIGHT); + } + + void updateThanksLog(String text) { + thanksLog = text; + repaint(THANK_INFO_X, MODULE_INFO_Y - FONT_SIZE, MODULE_INFO_WIDTH, MODULE_INFO_HEIGHT); + } + +} diff --git a/designer-realize/src/main/java/com/fr/start/common/SplashWindow.java b/designer-realize/src/main/java/com/fr/start/common/SplashWindow.java new file mode 100644 index 000000000..58a27dd7f --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/common/SplashWindow.java @@ -0,0 +1,70 @@ +package com.fr.start.common; + +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.stable.os.OperatingSystem; +import com.sun.awt.AWTUtilities; + +import javax.swing.*; +import java.awt.*; + +/** + * 启动画面窗口 + * + * @author vito + * @version 10.0 + * Created by vito on 2019/10/16 + */ +public class SplashWindow extends JFrame { + + private SplashPane splash; + + public SplashWindow() { + // alex:必须设置这个属性为true,才可以用透明背景 + System.setProperty("sun.java2d.noddraw", "true"); + + //slash pane + this.splash = new SplashPane(); + + splash.setBackground(null); + this.setContentPane(splash); + this.setSize(splash.getSplashDimension()); + + this.setAlwaysOnTop(false); + this.setUndecorated(true); + AWTUtilities.setWindowOpaque(this, false); + + //使窗体背景透明 + if (OperatingSystem.isWindows()) { + this.setBackground(new Color(0, 0, 0, 0)); + } + + GUICoreUtils.centerWindow(this); + } + + /** + * 注销窗口 + */ + @Override + public void dispose() { + super.dispose(); + } + + /** + * 设置在启动过程中, 动态改变的文本, 如 当前启动的模块信息 + * + * @param text 指定的文本 + */ + void updateModuleLog(String text) { + splash.updateModuleLog(text); + } + + void updateThanksLog(String text) { + splash.updateThanksLog(text); + } + + + public static void main(String[] args) { + SplashWindow splashWindow = new SplashWindow(); + splashWindow.setVisible(true); + } +} diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java index 31e818b3e..822a332f3 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java @@ -25,6 +25,7 @@ import com.fr.design.actions.insert.flot.FormulaFloatAction; import com.fr.design.actions.insert.flot.ImageFloatAction; import com.fr.design.actions.insert.flot.TextBoxFloatAction; import com.fr.design.bridge.DesignToolbarProvider; +import com.fr.design.constants.DesignerLaunchStatus; import com.fr.design.form.parameter.FormParaDesigner; import com.fr.design.fun.ElementUIProvider; import com.fr.design.gui.controlpane.NameObjectCreator; @@ -98,8 +99,8 @@ import com.fr.stable.xml.ObjectXMLWriterFinder; import com.fr.start.BBSGuestPaneProvider; import com.fr.xml.ReportXMLUtils; -import java.awt.Image; -import java.awt.image.BufferedImage; +import java.awt.*; +import java.awt.image.*; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -115,7 +116,7 @@ public class DesignerActivator extends Activator { @Override public void start() { - List markers = rightCollectMutable(InterMutableKey.Path); + List markers = findMutable(InterMutableKey.Path); for (LocaleMarker marker : markers) { if (marker.match(LocaleScope.DESIGN)) { DesignI18nImpl.getInstance().addResource(marker.getPath()); @@ -128,7 +129,12 @@ public class DesignerActivator extends Activator { storePassport(); AlphaFineHelper.switchConfig4Locale(); } - + + @Override + public void afterAllStart() { + DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE); + } + private void loadLogAppender() { logHandler = new LogHandler() { final DesignerLogAppender logAppender = new DesignerLogAppender(); diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java deleted file mode 100644 index e9bea2692..000000000 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.fr.start.module; - -import com.fr.module.Activator; -import com.fr.start.DesignerInitial; - -/** - * Created by juhaoyu on 2019-06-14. - */ -public class DesignerInitActivator extends Activator { - - @Override - public void start() { - - DesignerInitial.init(upFindSingleton(StartupArgs.class).get()); - } - - @Override - public void stop() { - - } -} diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerShowActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerShowActivator.java index 33ef015c1..d41db181f 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerShowActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerShowActivator.java @@ -10,16 +10,16 @@ import com.fr.start.DesignerInitial; * Created by juhaoyu on 2019-06-14. */ public class DesignerShowActivator extends Activator { - + @Override public void start() { - - EventDispatcher.fire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Module_Name_Designer")); - DesignerInitial.show(); + DesignerInitial.init(findSingleton(StartupArgs.class).get()); + EventDispatcher.asyncFire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Module_Name_Designer")); + DesignerInitial.prepare(); } - + @Override public void stop() { - + // void } } 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 9fb0ec2b9..c43fc8be8 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 @@ -1,11 +1,33 @@ package com.fr.start.module; +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.DesignerEnvManager; +import com.fr.design.fun.OemProcessor; +import com.fr.design.fun.impl.GlobalListenerProviderManager; +import com.fr.design.mainframe.messagecollect.StartupMessageCollector; +import com.fr.design.ui.util.UIUtil; +import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.DesignerPort; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; import com.fr.module.Activator; import com.fr.record.analyzer.EnableMetrics; import com.fr.record.analyzer.Metrics; -import com.fr.runtime.FineRuntime; +import com.fr.stable.BuildContext; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.start.OemHandler; import com.fr.start.ServerStarter; +import com.fr.start.SplashContext; +import com.fr.start.SplashStrategy; +import com.fr.start.common.SplashCommon; +import com.fr.start.server.FineEmbedServer; +import com.fr.value.NotNullLazyValue; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.concurrent.ExecutorService; /** * Created by juhaoyu on 2018/1/8. @@ -13,27 +35,117 @@ import com.fr.start.ServerStarter; @EnableMetrics public class DesignerStartup extends Activator { + private NotNullLazyValue startupArgsValue = new NotNullLazyValue() { + @NotNull + @Override + protected StartupArgs compute() { + return findSingleton(StartupArgs.class); + } + }; + + @Override + public void beforeAllStart() { + BuildContext.setBuildFilePath("/com/fr/stable/build.properties"); + // 检查是否是-Ddebug = true 启动 并切换对应的端口以及环境配置文件 + checkDebugStart(); + if (DesignUtils.isStarted()) { + // 如果端口被占用了 说明程序已经运行了一次,也就是说,已经建立一个监听服务器,现在只要给服务器发送命令就好了 + final String[] args = startupArgsValue.getValue().get(); + DesignUtils.clientSend(args); + FineLoggerFactory.getLogger().info("The Designer Has Been Started"); + System.exit(0); + return; + } + // 快快显示启动画面 + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + SplashContext.getInstance().registerSplash(createSplash()); + SplashContext.getInstance().show(); + } + }); + } + @Override @Metrics public void start() { startSub(PreStartActivator.class); - startSub("parallel"); + startSub(DesignerWorkspaceActivator.class); //designer模块启动好后,查看demo - browserDemo(); - startSub(StartFinishActivator.class); - FineRuntime.startFinish(); + browserDemoIfNeeded(); + startupEmbedServerIfNeeded(); + } + + private void startupEmbedServerIfNeeded() { + if (DesignerEnvManager.getEnvManager().isEmbedServerLazyStartup() + || FineEmbedServer.isRunning()) { + return; + } + ExecutorService service = newSingleThreadExecutor(new NamedThreadFactory("FineEmbedServerStart")); + service.submit(new Runnable() { + @Override + public void run() { + FineEmbedServer.start(); + } + }); + service.shutdown(); + } + + @Override + public void afterAllStart() { + GlobalListenerProviderManager.getInstance().init(); + // 启动日志收集 + StartupMessageCollector.getInstance().recordStartupLog(); + } + + private SplashStrategy createSplash() { + OemProcessor oemProcessor = OemHandler.findOem(); + if (oemProcessor != null) { + SplashStrategy splashStrategy = null; + try { + splashStrategy = oemProcessor.createSplashStrategy(); + } catch (Throwable e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (splashStrategy != null) { + return splashStrategy; + } + } + + return new SplashCommon(); } - private void browserDemo() { + private void browserDemoIfNeeded() { - if (findSingleton(StartupArgs.class) != null && findSingleton(StartupArgs.class).isDemo()) { + if (startupArgsValue.getValue().isDemo()) { ServerStarter.browserDemoURL(); } } + /** + * 在VM options里加入-Ddebug=true激活 + */ + private void checkDebugStart() { + + if (ComparatorUtils.equals("true", System.getProperty("debug"))) { + setDebugEnv(); + } + } + + /** + * 端口改一下,环境配置文件改一下。便于启动两个设计器,进行对比调试 + */ + private void setDebugEnv() { + + DesignUtils.setPort(DesignerPort.DEBUG_MESSAGE_PORT); + DesignerEnvManager.setEnvFile(new File(StableUtils.pathJoin( + ProductConstants.getEnvHome(), + ProductConstants.APP_NAME + "Env_debug.xml" + ))); + } @Override public void stop() { - + // void } } diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java index e1caf7ce9..f5231eafe 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java @@ -10,7 +10,6 @@ import com.fr.workspace.Workspace; import com.fr.workspace.WorkspaceEvent; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * Created by juhaoyu on 2019-06-14. @@ -44,7 +43,6 @@ public class DesignerWorkspaceActivator extends Activator { public void on(Event event, Workspace current) { startSub(EnvBasedModule.class); - startServer(current); } }); /*切换环境前,存储一下打开的所有文件对象,要先于 关闭相关模块部分 被触发*/ @@ -72,7 +70,8 @@ public class DesignerWorkspaceActivator extends Activator { // 切换后的环境是本地环境才启动内置服务器 if (current.isLocal()) { - ExecutorService service = Executors.newSingleThreadExecutor(new NamedThreadFactory("DesignerWorkspaceActivator")); + ExecutorService service = newSingleThreadExecutor( + new NamedThreadFactory("DesignerWorkspaceActivator")); service.submit(new Runnable() { @Override diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java index 9bf935740..ee57bb551 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java @@ -7,8 +7,10 @@ import com.fr.design.env.DesignerWorkspaceGenerator; import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.log.FineLoggerFactory; import com.fr.module.Activator; +import com.fr.value.NotNullLazyValue; import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; +import org.jetbrains.annotations.NotNull; /** @@ -17,12 +19,20 @@ import com.fr.workspace.Workspace; */ public class DesignerWorkspaceProvider extends Activator { + private NotNullLazyValue startupArgs = new NotNullLazyValue() { + @NotNull + @Override + protected StartupArgs compute() { + return findSingleton(StartupArgs.class); + } + }; + @Override public void start() { //检查环境 DesignerEnvManager.checkNameEnvMap(); - if (findSingleton(StartupArgs.class) != null && findSingleton(StartupArgs.class).isDemo()) { + if (startupArgs.getValue().isDemo()) { DesignerEnvManager.getEnvManager().setCurrentEnv2Default(); } else { try { @@ -40,12 +50,15 @@ public class DesignerWorkspaceProvider extends Activator { EnvChangeEntrance.getInstance().dealEvnExceptionWhenStartDesigner(); } } - DesignerLaunchStatus.setStatus(DesignerLaunchStatus.WORKSPACE_INIT_COMPLETE); } @Override public void stop() { - + // void } + @Override + public void afterAllStart() { + DesignerLaunchStatus.setStatus(DesignerLaunchStatus.WORKSPACE_INIT_COMPLETE); + } } diff --git a/designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java b/designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java index 2f565bb08..d3aec5897 100644 --- a/designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java @@ -2,28 +2,13 @@ package com.fr.start.module; import com.fr.design.DesignerEnvManager; import com.fr.design.RestartHelper; -import com.fr.design.fun.OemProcessor; import com.fr.design.i18n.Toolkit; import com.fr.design.utils.DesignUtils; -import com.fr.design.utils.DesignerPort; import com.fr.event.EventDispatcher; import com.fr.general.CloudCenter; -import com.fr.general.ComparatorUtils; import com.fr.general.GeneralContext; -import com.fr.log.FineLoggerFactory; import com.fr.module.Activator; import com.fr.module.ModuleEvent; -import com.fr.stable.BuildContext; -import com.fr.stable.OperatingSystem; -import com.fr.stable.ProductConstants; -import com.fr.stable.StableUtils; -import com.fr.start.OemHandler; -import com.fr.start.SplashContext; -import com.fr.start.SplashStrategy; -import com.fr.start.fx.SplashFx; -import com.fr.start.jni.SplashMac; - -import java.io.File; /** * Created by juhaoyu on 2018/1/8. @@ -32,24 +17,7 @@ public class PreStartActivator extends Activator { @Override public void start() { - - BuildContext.setBuildFilePath("/com/fr/stable/build.properties"); - // 如果端口被占用了 说明程序已经运行了一次,也就是说,已经建立一个监听服务器,现在只要给服务器发送命令就好了 - final String[] args = findSingleton(StartupArgs.class).get(); - // 检查是否是-Ddebug = true 启动 并切换对应的端口以及环境配置文件 - checkDebugStart(); - if (DesignUtils.isStarted()) { - DesignUtils.clientSend(args); - FineLoggerFactory.getLogger().info("The Designer Has Been Started"); - System.exit(0); - return; - } - RestartHelper.deleteRecordFilesWhenStart(); - - SplashContext.getInstance().registerSplash(createSplash()); - - SplashContext.getInstance().show(); //初始化 EventDispatcher.fire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Basic_Initializing")); // 完成初始化 @@ -64,38 +32,7 @@ public class PreStartActivator extends Activator { @Override public void stop() { - - } - - private void checkDebugStart() { - - if (isDebug()) { - setDebugEnv(); - } - } - - - /** - * 在VM options里加入-Ddebug=true激活 - * - * @return isDebug - */ - private boolean isDebug() { - - return ComparatorUtils.equals("true", System.getProperty("debug")); - } - - - //端口改一下,环境配置文件改一下。便于启动两个设计器,进行对比调试 - private void setDebugEnv() { - - DesignUtils.setPort(DesignerPort.DEBUG_MESSAGE_PORT); - String debugXMlFilePath = StableUtils.pathJoin( - ProductConstants.getEnvHome(), - ProductConstants.APP_NAME + "Env_debug.xml" - ); - DesignerEnvManager.setEnvFile( - new File(debugXMlFilePath)); + // void } private void initLanguage() { @@ -107,27 +44,4 @@ public class PreStartActivator extends Activator { return new String[]{".cpt", ".xls", ".xlsx", ".frm", ".form", ".cht", ".chart"}; } - - private SplashStrategy createSplash() { - - OemProcessor oemProcessor = OemHandler.findOem(); - if (oemProcessor != null) { - SplashStrategy splashStrategy = null; - try { - splashStrategy = oemProcessor.createSplashStrategy(); - } catch (Throwable e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - if (splashStrategy != null) { - return splashStrategy; - } - } - // 这里可以开接口加载自定义启动画面 - if (OperatingSystem.isWindows()) { - return new SplashFx(); - } else if (OperatingSystem.isMacOS()) { - return new SplashMac(); - } - return new SplashFx(); - } } diff --git a/designer-realize/src/main/java/com/fr/start/module/StartFinishActivator.java b/designer-realize/src/main/java/com/fr/start/module/StartFinishActivator.java deleted file mode 100644 index 41f662a88..000000000 --- a/designer-realize/src/main/java/com/fr/start/module/StartFinishActivator.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.fr.start.module; - -import com.fr.design.fun.impl.GlobalListenerProviderManager; -import com.fr.module.Activator; - -/** - * Created by juhaoyu on 2018/1/8. - */ -public class StartFinishActivator extends Activator { - - @Override - public void start() { - GlobalListenerProviderManager.getInstance().init(); - } - - @Override - public void stop() { - } -} diff --git a/designer-realize/src/main/resources/com/fr/design/images/splash_10.png b/designer-realize/src/main/resources/com/fr/design/images/splash_10.png new file mode 100644 index 000000000..088d124b9 Binary files /dev/null and b/designer-realize/src/main/resources/com/fr/design/images/splash_10.png differ diff --git a/designer-realize/src/main/resources/com/fr/design/images/splash_10@2x.png b/designer-realize/src/main/resources/com/fr/design/images/splash_10@2x.png new file mode 100644 index 000000000..0ce87ae6f Binary files /dev/null and b/designer-realize/src/main/resources/com/fr/design/images/splash_10@2x.png differ