package com.fr.start; import com.fanruan.gui.UiInspector; import com.fine.theme.icon.LazyIcon; import com.fr.base.function.UITerminator; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignerEnvManager; import com.fr.design.actions.file.WebPreviewUtils; import com.fr.design.actions.file.newReport.NewPolyReportAction; import com.fr.design.actions.file.newReport.NewWorkBookAction; import com.fr.design.actions.server.ServerConfigManagerAction; import com.fr.design.actions.server.TemplateThemeManagerAction; import com.fr.design.actions.server.WidgetManagerAction; import com.fr.design.base.mode.DesignModeContext; import com.fr.design.carton.latency.DesignerLatencyMetric; import com.fr.design.carton.SwitchForSwingChecker; import com.fr.design.constants.DesignerLaunchStatus; import com.fr.design.deeplink.DeepLinkManager; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.MultiTemplateTabPane; import com.fr.design.fun.MenuHandler; import com.fr.design.fun.OemProcessor; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UICombinationButton; import com.fr.design.gui.ibutton.UISaveForbiddenButton; import com.fr.design.gui.imenu.UIMenuItem; import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.ActiveKeyGenerator; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.InformationCollector; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JWorkBook; import com.fr.design.mainframe.alphafine.component.AlphaFinePane; import com.fr.design.mainframe.bbs.UserInfoLabel; import com.fr.design.mainframe.bbs.UserInfoPane; import com.fr.design.mainframe.guide.entry.GuideEntryPane; import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.MenuDef; import com.fr.design.menu.SeparatorDef; import com.fr.design.menu.ShortCut; import com.fr.design.module.ChartEmptyDataStyleAction; import com.fr.design.module.ChartPreStyleAction; import com.fr.design.module.DesignModuleFactory; import com.fr.design.monitor.DesignerLifecycleMonitorContext; import com.fr.design.notification.ui.NotificationCenterPane; import com.fr.design.share.SharableManager; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.DesignUtils; import com.fr.design.utils.DesignerPort; import com.fr.design.utils.concurrent.ThreadFactoryBuilder; import com.fr.env.utils.DesignerInteractionHistory; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.log.SystemOutLoggerProvider; import com.fr.module.Module; import com.fr.module.ModuleContext; import com.fr.module.engine.event.LifecycleErrorEvent; import com.fr.runtime.FineRuntime; import com.fr.stable.ProductConstants; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.lifecycle.FineLifecycleFatalError; import com.fr.stable.xml.XMLTools; import com.fr.start.common.DesignerStartupContext; import com.fr.start.common.SplashCommon; import com.fr.start.module.StartupArgs; import com.fr.start.preload.PreLoadService; import com.fr.start.server.ServerTray; import com.fr.van.chart.map.server.ChartMapEditorAction; import com.fr.workspace.WorkContext; import javax.swing.JComponent; import javax.swing.JPanel; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.io.File; import java.util.ArrayList; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class MainDesigner extends BaseDesigner { private static final int TOOLBARPANEVGAP = -4; private static final int PREVIEW_DOWN_X_GAP = 92; private static final int GAP = 7; private static final String OLD_ENV_FOLDER_71 = ".FineReport71"; private static final String OLD_ENV_FOLDER_70 = ".FineReport70"; private UserInfoPane userInfoPane; private UIButton saveButton; private UIButton undo; private UIButton redo; private UIButton[] upToolBar; private UICombinationButton run; public MainDesigner(String[] args) { super(args); } /** * 设计器启动的Main方法 * * @param args 参数 */ public static void main(String[] args) { DesignerStartupContext.getRecorder().start(); // 设置一下默认的logger,启动后再Reset FineLoggerFactory.setLogger(SystemOutLoggerProvider.getInstance()); showSplash(); DesignerEnvManager.getEnvManager(); startPreload0(); DesignerLifecycleMonitorContext.getMonitor().beforeStart(); //启动运行时 FineRuntime.start(); //等 FineRuntime 启动后启动 DeepLinkManager.getInstance().start(args); startPreload1(); DesignerSubListener.getInstance().start(); EventDispatcher.listen(LifecycleErrorEvent.SELF, new Listener() { @Override public void on(Event event, FineLifecycleFatalError param) { LifecycleFatalErrorHandler.getInstance().handle(param); } }); Module designerRoot = ModuleContext.parseRoot("designer-startup.xml"); FineLoggerFactory.getLogger().debug("Designer prepared.Time used {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS)); //传递启动参数 designerRoot.setSingleton(StartupArgs.class, new StartupArgs(args)); try { designerRoot.start(); } catch (FineLifecycleFatalError fatal) { LifecycleFatalErrorHandler.getInstance().handle(fatal); } if (WorkContext.getCurrent().isLocal()) { //初始化一下serverTray ServerTray.init(); } FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS)); DesignerStartupContext.getRecorder().stop(); SwitchForSwingChecker.initThreadMonitoring(); DesignerLatencyMetric.getInstance().start(); installUIDevModeTools(); } /** * 进入UI开发者模式 */ private static void installUIDevModeTools() { if (DesignerUIModeConfig.getInstance().isUIDevMode()) { new UiInspector(); } } /** * 在 {@link FineRuntime#start()} 运行后 */ private static void startPreload1() { DesignUtils.initLookAndFeel(); DesignerLaunchStatus.setStatusAndAsyncFire(DesignerLaunchStatus.UI_PRE_INIT_COMPLETE); } /** * 在 {@link FineRuntime#start()} 运行前 */ private static void startPreload0() { PreLoadService.getInstance().addRunnable(() -> { if (DesignUtils.isPortOccupied()) { UITerminator action = new UITerminator() { @Override protected void doRun() { StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.PORT_OCCUPIED.getId(), DesignerErrorMessage.PORT_OCCUPIED.getMessage()); DesignerPort.getInstance().resetPort(); } }; action.run(); } }); } private static void showSplash() { // 快快显示启动画面 // vito: 这里必须用 wait, 不然会导致莫名其妙的问题 UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { SplashContext.getInstance().registerSplash(createSplash()); SplashContext.getInstance().show(); } }); } /** * 创建新建文件的快捷方式数组。 * * @return 返回快捷方式的数组 */ @Override public ShortCut[] createNewFileShortCuts() { ArrayList shortCuts = new ArrayList(); // shortCuts.add(new NewWorkBookXAction()); shortCuts.add(new NewWorkBookAction()); // 决策报表、聚合报表归入其他 MenuDef newOtherFileMenuDef = new MenuDef(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_M_New_Other_Template")); newOtherFileMenuDef.setIcon(new LazyIcon("createOther")); try { // todo:菜单 if (DesignModuleFactory.getNewFormAction() != null) { newOtherFileMenuDef.addShortCut((ShortCut) DesignModuleFactory.getNewFormAction().newInstance()); } } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } newOtherFileMenuDef.addShortCut(new NewPolyReportAction()); shortCuts.add(newOtherFileMenuDef); return shortCuts.toArray(new ShortCut[0]); } @Override protected MenuDef createServerMenuDef(ToolBarMenuDockPlus plus) { MenuDef menuDef = super.createServerMenuDef(plus); if (WorkContext.getCurrent() == null) { return menuDef; } if (!DesignerMode.isAuthorityEditing()) { menuDef.addShortCut(SeparatorDef.DEFAULT); if (WorkContext.getCurrent().isRoot()) { // 服务器配置 menuDef.addShortCut(new ServerConfigManagerAction()); JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (JTemplate.isValid(jt)) { // 模板主题管理 menuDef.addShortCut(new TemplateThemeManagerAction()); } // 控件管理 menuDef.addShortCut(new WidgetManagerAction()); // 图标预定义配色、图标空数据提示、地图配置 menuDef.addShortCut(new ChartPreStyleAction(), new ChartEmptyDataStyleAction(), new ChartMapEditorAction()); } insertMenu(menuDef, MenuHandler.SERVER); } return menuDef; } /** * 创建设计器上几个比较大的图标:新建cpt,保存,前进,后退,运行。 * * @return 返回大图标对应的工具栏 */ @Override public UICombinationButton createLargeToolbar() { UICombinationButton largeToolbar = createRunButton(); return largeToolbar; } private JPanel generateEmptyGap(final int width) { JPanel panel = new JPanel() { @Override public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); dim.width = width; return dim; } }; panel.setBackground(null); panel.setOpaque(false); return panel; } /** * 创建上面一排的工具栏按钮 * * @return 按钮 */ @Override public UIButton[] createUp() { if (upToolBar == null) { createSaveButton(); createUndoButton(); createRedoButton(); return upToolBar = new UIButton[]{saveButton, undo, redo}; } return upToolBar; } private void createSaveButton() { saveButton = new UIButton(new LazyIcon("save")); saveButton.setToolTipText(KeySetUtils.SAVE_TEMPLATE.getMenuKeySetName()); saveButton.set4ToolbarButton(); saveButton.addActionListener(e -> { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); jt.stopEditing(); jt.saveDirectly(); jt.requestFocus(); SharableManager.saveTemplate(jt); }); } private void createUndoButton() { undo = new UIButton(new LazyIcon("undo")); undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName()); undo.set4ToolbarButton(); undo.addActionListener(e -> { JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); if (jt != null) { jt.undo(); } }); } private void createRedoButton() { redo = new UIButton(new LazyIcon("redo")); redo.setToolTipText(KeySetUtils.REDO.getMenuKeySetName()); redo.set4ToolbarButton(); redo.addActionListener(e -> { JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); if (jt != null) { jt.redo(); } }); } private UICombinationButton createRunButton() { run = new UICombinationButton(new UISaveForbiddenButton(Toolkit.i18nText("Fine-Design_Basic_Preview"), new LazyIcon("run").white()), new UISaveForbiddenButton(new LazyIcon("triangle_down").white())); run.addLeftClickLister(mouseEvent -> { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (jt == null || jt.isSaving()) { return; } WebPreviewUtils.preview(jt); }); run.addRightClickLister(mouseEvent -> { final JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (jt == null) { return; } UIPopupMenu menu = new UIPopupMenu(); UIMenuItem[] items = jt.createMenuItem4Preview(); for (UIMenuItem item : items) { menu.add(item); } menu.show(run, 0, run.getHeight() + 1); }); run.setPrimary(); run.getLeftButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview")); run.getRightButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Dropdown_More_Preview")); return run; } @Override protected void refreshLargeToolbarState() { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (!JTemplate.isValid(jt)) { return; } saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode() && jt.checkEnable()); MultiTemplateTabPane.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList()); MultiTemplateTabPane.getInstance().repaint(); if (DesignerEnvManager.getEnvManager().isSupportUndo()) { undo.setEnabled(jt.canUndo()); redo.setEnabled(jt.canRedo()); } else { undo.setEnabled(false); redo.setEnabled(false); } run.getLeftButton().setText(jt.getPreviewType().nameForPopupItem()); } /** * 生成工具栏 * * @param toolbarComponent 工具栏 * @param plus 对象 * @return 更新后的toolbar */ @Override public JComponent resetToolBar(JComponent toolbarComponent, ToolBarMenuDockPlus plus) { //如果是处于权限编辑状态 if (DesignerMode.isAuthorityEditing()) { if (plus instanceof JWorkBook && plus.toolbars4Target() == null) { //聚合块编辑 return super.polyToolBar(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Privilege_Poly_Block_Edit")); } else { return plus.toolBar4Authority(); } } switch (plus.toolbarPanes4Form().length) { case 0: return super.resetToolBar(toolbarComponent, plus); case 1: return plus.toolbarPanes4Form()[0]; default: { JPanel toolbarPane; toolbarPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); toolbarPane.setFocusable(true); JComponent[] paneArray = plus.toolbarPanes4Form(); for (JComponent component : paneArray) { toolbarPane.add(component); } return toolbarPane; } } } /** * 生成报表设计和表单设计的编辑区域 * * @return 返回编辑区域 */ @Override public JTemplate createNewTemplate() { return new JWorkBook(); } /** * 创建论坛登录面板, chart那边不需要 * * @return 面板组件 */ @Override public Component createBBSLoginPane() { if (userInfoPane == null) { userInfoPane = UserInfoPane.getInstance(); } return userInfoPane; } /** * 创建alphafine打开面板 * * @return 面板组件 */ @Override public Component createAlphaFinePane() { return AlphaFinePane.getAlphaFinePane(); } public Component createGuideEntryPane() { return GuideEntryPane.getGuideEntryPane(); } public Component createNotificationCenterPane() { return NotificationCenterPane.getNotificationCenterPane(); } /** * 收集用户信息吗 */ @Override protected void collectUserInformation() { //定制的就不弹出来了 if (!ComparatorUtils.equals(ProductConstants.APP_NAME, ProductConstants.DEFAULT_APP_NAME)) { return; } DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); final String key = envManager.getActivationKey(); //本地验证通过 if (ActiveKeyGenerator.localVerify(key)) { onLineVerify(envManager, key); UserInfoLabel.showBBSDialog(); return; } if (StableUtils.checkDesignerActive(readOldKey())) { //只要有老的key, 就不弹窗, 下次启动的时候, 在线验证下就行. String newKey = ActiveKeyGenerator.generateActiveKey(); envManager.setActivationKey(newKey); UserInfoLabel.showBBSDialog(); return; } CollectUserInformationDialog activeDialog = new CollectUserInformationDialog( DesignerContext.getDesignerFrame()); activeDialog.setVisible(true); } private void onLineVerify(DesignerEnvManager envManager, final String key) { int status = envManager.getActiveKeyStatus(); //没有联网验证过 if (status != 0) { ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() .setNameFormat("net-verify-thread-%s").build(); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(1), namedThreadFactory); threadPoolExecutor.execute(new Runnable() { @Override public void run() { ActiveKeyGenerator.onLineVerify(key); } }); } } private File getOldEnvFile(String folderName) { String userHome = System.getProperty("user.home"); if (userHome == null) { userHome = System.getProperty("userHome"); } String filePath = StableUtils.pathJoin(userHome, folderName, ProductConstants.APP_NAME + "Env.xml"); return new File(filePath); } private String getOldActiveKeyFromFile(File envFile) { if (!envFile.exists()) { return StringUtils.EMPTY; } DesignerEnvManager temp = new DesignerEnvManager(); try { XMLTools.readFileXML(temp, envFile); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } return temp.getActivationKey(); } //默认只从7.0和711的设计器里读取key private String readOldKey() { File file71 = getOldEnvFile(OLD_ENV_FOLDER_71); if (!file71.exists()) { File file70 = getOldEnvFile(OLD_ENV_FOLDER_70); return getOldActiveKeyFromFile(file70); } return getOldActiveKeyFromFile(file71); } /** * 设计器退出时, 做的一些操作. */ @Override public void shutDown() { InformationCollector collector = InformationCollector.getInstance(); collector.collectStopTime(); collector.saveXMLFile(); DesignerInteractionHistory historyCollector = DesignerInteractionHistory.getInstance(); historyCollector.saveXMLFile(); } private static 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(); } }