diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index 4b8c41659c..75afa6e934 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -277,12 +277,15 @@ public class EnvChangeEntrance { @Override public void done() { DesignerEnvManager.getEnvManager().setCurEnvName(envName); - DesignUtils.refreshDesignerFrame(); DesignTableDataManager.fireDSChanged(new HashMap()); if (WorkContext.getCurrent().isLocal()) { //初始化一下serverTray ServerTray.init(); } + SwingUtilities.invokeLater(() -> { + DesignUtils.refreshDesignerFrameAfterEnvChange(); + HistoryTemplateListCache.getInstance().load(); + }); } }); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java index 136181bcd8..692f940d69 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java @@ -117,7 +117,7 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC @Override public void ancestorAdded(AncestorEvent event) { registerDSChangeListener(); - UIUtil.invokeLaterIfNeeded(() -> refresh(DesignTableDataManager.getEditingTableDataSource())); + refresh(DesignTableDataManager.getEditingTableDataSource()); } @Override @@ -132,20 +132,40 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC } /** - * refresh ComboBox + * 刷新数据源并更新下拉框的模型和选中项 * - * @param source 数据源 + * @param source 数据源,用于刷新模型 */ public void refresh(TableDataSource source) { + UIUtil.executeAsyncTaskAndUpdateUI( + () -> { + setResMap(source); + setDsMap(); + return null; + }, + result -> refreshComboBoxModel() + ); + } + + /** + * 刷新下拉框模型,同时保留当前选中的数据项 + *

+ * 1. 获取下拉框中当前选中的数据项 + * 2. 刷新下拉框的模型(清空并重新填充数据),此操作会重置选中的数据项 + * 3. 在刷新模型后,恢复之前选中的数据项 + *

+ * 关于 `refreshModel` 的作用: + * 1. **抑制事件触发**:下拉框模型在调用 `addElement` 方法时会触发 `fireItemStateChanged` 事件, + * 通过标记 `refreshModel`,可以在刷新过程中抑制此事件 + * 2. **处理异步和顺序问题**:由于取数操作是异步的,可能会导致回调后的 UI 操作与其他逻辑(如 `populateBean`)的调用顺序交错。 + * 标记 `refreshModel` 可确保在刷新模型时,不触发选中事件,从而避免逻辑干扰 + * 3. **逻辑清晰性**:刷新模型本质上是更新数据源的操作,不应触发与用户交互相关的选中事件,避免对上层逻辑造成额外负担 + */ + private void refreshComboBoxModel() { refreshModel = true; - setResMap(source); - setDsMap(); - // 获取当前选中的数据项 - TableDataWrapper dataWrapper = getSelectedItem(); - // 更新下拉模型 - refreshComboBoxModel(); - //处理已选中的数据项 - updateSelectedItem(dataWrapper); + TableDataWrapper selectedItem = getSelectedItem(); + refreshModel(); + updateSelectedItem(selectedItem); refreshModel = false; } @@ -157,7 +177,7 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC dsMap = DesignTableDataManager.getAllDataSetIncludingProcedure(resMap); } - private void refreshComboBoxModel() { + private void refreshModel() { //创建ComboBox模型并设置 DefaultComboBoxModel model = new DefaultComboBoxModel(); this.setModel(model); diff --git a/designer-base/src/main/java/com/fr/design/env/HttpWorkspaceConnector.java b/designer-base/src/main/java/com/fr/design/env/HttpWorkspaceConnector.java index f8a4cc6739..95b512fcb6 100644 --- a/designer-base/src/main/java/com/fr/design/env/HttpWorkspaceConnector.java +++ b/designer-base/src/main/java/com/fr/design/env/HttpWorkspaceConnector.java @@ -9,6 +9,7 @@ import com.fanruan.workplace.network.RemoteNetworkRepository; import com.fr.decision.webservice.bean.authentication.LoginRequestInfoBean; import com.fr.decision.webservice.bean.authentication.LoginResponseInfoBean; import com.fr.stable.StringUtils; +import com.fr.start.common.DesignerStartupPool; import com.fr.workspace.connect.WorkspaceClient; import com.fr.workspace.connect.WorkspaceConnection; import com.fr.workspace.connect.WorkspaceConnectionInfo; @@ -23,6 +24,7 @@ import com.fr.workspace.server.repository.connect.FineWorkspaceHttpClient; import java.net.InetAddress; import java.util.Map; import java.util.UUID; +import java.util.concurrent.CompletableFuture; /** * 远程环境连接器 @@ -73,6 +75,29 @@ public class HttpWorkspaceConnector implements WorkspaceConnector { Stub stub = entry.getValue(); stub.clearProxy(); } + //执行登录操作并更新client + CompletableFuture loginFuture = CompletableFuture.runAsync(() -> { + try { + login(client, connectionInfo); + } catch (Exception e) { + throw new RemoteDesignConnectionException(e, StringUtils.EMPTY); + } + }, DesignerStartupPool.common()); + //测试FR连接 + CompletableFuture testConnectFuture = CompletableFuture.supplyAsync(() -> { + try { + return RemoteNetworkRepository.getInstance().testConnect(); + } catch (RemoteDesignNoAuthException | RemoteServiceErrorException e) { + throw e; + } catch (Exception e) { + throw new RemoteDesignConnectionException(e, StringUtils.EMPTY); + } + }, DesignerStartupPool.common()); + CompletableFuture.allOf(loginFuture, testConnectFuture).join(); + return testConnectFuture.get(); + } + + private void login(FineWorkspaceHttpClient client, WorkspaceConnectionInfo connectionInfo) throws Exception { Map loginConfigMap = RemoteAuthorityRepository.getInstance().getLoginConfigMap(); long timeout = Long.parseLong(String.valueOf(loginConfigMap.get(RemoteAuthoritySource.LOGIN_TIMEOUT))); boolean rememberLogin = (boolean) loginConfigMap.get(RemoteAuthoritySource.SUPPORT_REMEMBER_LOGIN); @@ -85,13 +110,6 @@ public class HttpWorkspaceConnector implements WorkspaceConnector { client.updateConnection(connection); client.setRememberLogin(rememberLogin); client.setTimeout(timeout); - try { - return RemoteNetworkRepository.getInstance().testConnect(); - } catch (RemoteDesignNoAuthException | RemoteServiceErrorException e) { - throw e; - } catch (Exception e) { - throw new RemoteDesignConnectionException(e, StringUtils.EMPTY); - } } private LoginRequestInfoBean createLoginBean(WorkspaceConnectionInfo connectionInfo, boolean rememberLogin) { diff --git a/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java b/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java index 43da357c40..741192fa01 100644 --- a/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java +++ b/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java @@ -10,11 +10,8 @@ import com.fr.report.DesignAuthority; import com.fr.stable.CoreConstants; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; -import com.fr.workspace.server.authority.AuthorityOperator; -import com.fr.workspace.server.authority.decision.DecisionOperator; -import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository; +import com.fr.workspace.server.repository.WorkplaceConstants; -import java.lang.reflect.UndeclaredThrowableException; import java.util.ArrayList; public class NodeAuthProcessor { @@ -43,8 +40,7 @@ public class NodeAuthProcessor { if (!WorkContext.getCurrent().isLocal()) { try { String userName = WorkContext.getCurrent().getConnection().getUserName(); - DesignAuthority[] authorities = null; - authorities = RemoteAuthorityRepository.getInstance().getAuthorities(WorkContext.getCurrent().getConnection().getUserName()); + DesignAuthority[] authorities = WorkplaceConstants.getAuthorities(); // 远程设计获取设计成员的权限列表 DesignAuthority authority = null; diff --git a/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java b/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java index b807123b19..56cb1bd988 100644 --- a/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java +++ b/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java @@ -219,7 +219,7 @@ public class TemplateTreePane extends JPanel implements FileOperations { * 刷新 */ public void refreshDockingView() { - reportletsTree.setFileNodeFilter(new IOFileNodeFilter(TemplateRepository.getInstance().getSupportedTypes())); + reportletsTree.setFileNodeFilter(new IOFileNodeFilter(FileNodeFILE.supportTypes)); reportletsTree.refreshEnv(); } diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java index ad9151fdbc..e43e4f48df 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java @@ -3,8 +3,7 @@ package com.fr.design.gui.ibutton; import javax.swing.Icon; import javax.swing.JPanel; import java.awt.BorderLayout; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.event.ActionEvent; import java.util.function.Consumer; import static com.fine.theme.utils.FineClientProperties.BUTTON_BORDER; @@ -33,8 +32,8 @@ public class UICombinationButton extends JPanel { protected UIButton rightButton; - private Consumer leftClickLister; - private Consumer rightClickLister; + private Consumer leftClickLister; + private Consumer rightClickLister; protected void leftButtonClickEvent() { // 左边按钮点击事件 @@ -54,7 +53,7 @@ public class UICombinationButton extends JPanel { * * @param lister 监听 */ - public void addLeftClickLister(Consumer lister) { + public void addLeftActionListener(Consumer lister) { this.leftClickLister = lister; } @@ -63,7 +62,7 @@ public class UICombinationButton extends JPanel { * * @param lister 监听 */ - public void addRightClickLister(Consumer lister) { + public void addRightActionListener(Consumer lister) { this.rightClickLister = lister; } @@ -73,25 +72,18 @@ public class UICombinationButton extends JPanel { leftButton.putClientProperty(BUTTON_BORDER, BUTTON_BORDER_LEFT_ROUND_RECT); rightButton = right; rightButton.putClientProperty(BUTTON_BORDER, BUTTON_BORDER_RIGHT_ROUND_RECT); - leftButton.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (leftClickLister != null) { - leftClickLister.accept(e); - } else { - leftButtonClickEvent(); - } + leftButton.addActionListener(e -> { + if (leftClickLister != null) { + leftClickLister.accept(e); + } else { + leftButtonClickEvent(); } }); - rightButton.addMouseListener(new MouseAdapter() { - - @Override - public void mouseClicked(MouseEvent e) { - if (rightClickLister != null) { - rightClickLister.accept(e); - } else { - rightButtonClickEvent(); - } + rightButton.addActionListener(e -> { + if (rightClickLister != null) { + rightClickLister.accept(e); + } else { + rightButtonClickEvent(); } }); diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java index 13d1d2490f..f911891a63 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java +++ b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java @@ -1,6 +1,7 @@ package com.fr.design.gui.itree.filetree; import com.fr.base.extension.FileExtension; +import com.fr.file.FileNodeFILE; import com.fr.general.GeneralContext; import com.fr.plugin.context.PluginContext; import com.fr.plugin.injectable.PluginModule; @@ -9,7 +10,6 @@ import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEventListener; import com.fr.report.ExtraReportClassManager; import com.fr.report.fun.ReportSupportedFileProvider; -import com.fanruan.repository.TemplateRepository; import java.util.Arrays; import java.util.LinkedHashSet; @@ -59,7 +59,7 @@ public class FileNodeConstants { for (ReportSupportedFileProvider provider : providers) { addAppExtensions(provider.getFileExtensions()); } - supportFileType.addAll(Arrays.asList(TemplateRepository.getInstance().getSupportedTypes())); + supportFileType.addAll(Arrays.asList(FileNodeFILE.supportTypes)); } finally { rwl.writeLock().unlock(); diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java b/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java index bf0ca09335..7601e8641c 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java +++ b/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/UserObjectRefreshJTree.java @@ -1,11 +1,14 @@ package com.fr.design.gui.itree.refreshabletree; import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.ui.util.UIUtil; import com.fr.general.NameObject; import com.fr.design.gui.itree.refreshabletree.loader.ChildrenLoaderFactory; import com.fr.general.ComparatorUtils; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.log.FineLoggerFactory; +import java.util.concurrent.ExecutionException; import javax.swing.*; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; @@ -33,8 +36,8 @@ public abstract class UserObjectRefreshJTree> extends } /* - * 判断eTreeNode是否需要Refresh,可提前中止,返回true则表示提前中止,不需要Refresh - */ + * 判断eTreeNode是否需要Refresh,可提前中止,返回true则表示提前中止,不需要Refresh + */ @Override protected boolean interceptRefresh(ExpandMutableTreeNode eTreeNode) { if (eTreeNode.getUserObject() instanceof UserObjectOP) { @@ -42,22 +45,32 @@ public abstract class UserObjectRefreshJTree> extends } return eTreeNode.getChildCount() == 0 || ((ExpandMutableTreeNode) eTreeNode.getFirstChild()).getUserObject() == PENDING; } + private boolean populating = false; /** * Populate */ public void populate(T userObject) { + if (populating) { + // 避免连续刷新 + return; + } + populating = true; DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel(); ExpandMutableTreeNode root = (ExpandMutableTreeNode) treeModel.getRoot(); root.setUserObject(userObject); root.removeAllChildren(); - - ExpandMutableTreeNode[] children = loadChildTreeNodes(root); - for (int i = 0; i < children.length; i++) { - root.add(children[i]); - } - treeModel.reload(root); - root.expandCurrentTreeNode(this); + UIUtil.executeAsyncTaskAndUpdateUI( + () -> loadChildTreeNodes(root), + expandMutableTreeNodes -> { + for (ExpandMutableTreeNode child : expandMutableTreeNodes) { + root.add(child); + } + treeModel.reload(root); + root.expandCurrentTreeNode(UserObjectRefreshJTree.this); + }, + () -> populating = false + ); } @Override @@ -85,8 +98,8 @@ public abstract class UserObjectRefreshJTree> extends } /* - * 根据NameObject取TreePath - */ + * 根据NameObject取TreePath + */ public TreePath getTreePathByNameObject(NameObject nameObject) { if (nameObject == null) { return null; @@ -158,6 +171,7 @@ public abstract class UserObjectRefreshJTree> extends } } + @Override public void mouseReleased(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { diff --git a/designer-base/src/main/java/com/fr/design/hyperlink/AbstractHyperNorthPane.java b/designer-base/src/main/java/com/fr/design/hyperlink/AbstractHyperNorthPane.java index 1ed57797ac..e52c07d76a 100644 --- a/designer-base/src/main/java/com/fr/design/hyperlink/AbstractHyperNorthPane.java +++ b/designer-base/src/main/java/com/fr/design/hyperlink/AbstractHyperNorthPane.java @@ -31,11 +31,11 @@ public abstract class AbstractHyperNorthPane extends BasicB /** * 对话框高度输入框 */ - private UISpinner heightTextFiled; + private UISpinner heightSpinner; /** * 对话框宽度输入框 */ - private UISpinner widthTextFiled; + private UISpinner widthSpinner; public AbstractHyperNorthPane() { @@ -60,12 +60,12 @@ public abstract class AbstractHyperNorthPane extends BasicB final JPanel newWindowConfPane = new JPanel(new BorderLayout()); UILabel heightLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Height")); - heightTextFiled = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_H_VALUE); + heightSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_H_VALUE); UILabel widthLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Designer_Width")); - widthTextFiled = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_V_VALUE); + widthSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_V_VALUE); newWindowConfPane.add(column(10, - row(cell(heightLabel).weight(0.2), cell(heightTextFiled).weight(0.8)), - row(cell(widthLabel).weight(0.2), cell(widthTextFiled).weight(0.8)) + row(cell(heightLabel).weight(0.2), cell(heightSpinner).weight(0.8)), + row(cell(widthLabel).weight(0.2), cell(widthSpinner).weight(0.8)) ).getComponent()); JPanel centerPanel = new JPanel(new BorderLayout()); @@ -104,28 +104,28 @@ public abstract class AbstractHyperNorthPane extends BasicB this.targetFrameComboBox = targetFrameComboBox; } - public UISpinner getHeightTextFiled() { - return heightTextFiled; + public UISpinner getHeightSpinner() { + return heightSpinner; } - public void setHeightTextFiled(UISpinner heightTextFiled) { - this.heightTextFiled = heightTextFiled; + public void setHeightSpinner(UISpinner heightSpinner) { + this.heightSpinner = heightSpinner; } - public UISpinner getWidthTextFiled() { - return widthTextFiled; + public UISpinner getWidthSpinner() { + return widthSpinner; } - public void setWidthTextFiled(UISpinner widthTextFiled) { - this.widthTextFiled = widthTextFiled; + public void setWidthSpinner(UISpinner widthSpinner) { + this.widthSpinner = widthSpinner; } @Override public void populateBean(T link) { String name = link.getTargetFrame(); targetFrameComboBox.setSelectedIndex(HyperlinkTargetFrame.convert(name)); - heightTextFiled.setValue(link.getHeight() == 0 ? DEFAULT_H_VALUE : link.getHeight()); - widthTextFiled.setValue(link.getWidth() == 0 ? DEFAULT_V_VALUE : link.getWidth()); + heightSpinner.setValue(link.getHeight() == 0 ? DEFAULT_H_VALUE : link.getHeight()); + widthSpinner.setValue(link.getWidth() == 0 ? DEFAULT_V_VALUE : link.getWidth()); populateSubHyperlinkBean(link); } @@ -145,8 +145,8 @@ public abstract class AbstractHyperNorthPane extends BasicB public void updateBean(T link) { updateSubHyperlinkBean(link); link.setTargetFrame(HyperlinkTargetFrame.parse(targetFrameComboBox.getSelectedIndex()).getName()); - link.setHeight(Utils.objectToNumber(heightTextFiled.getValue(), false).intValue()); - link.setWidth(Utils.objectToNumber(widthTextFiled.getValue(), false).intValue()); + link.setHeight(Utils.objectToNumber(heightSpinner.getValue(), false).intValue()); + link.setWidth(Utils.objectToNumber(widthSpinner.getValue(), false).intValue()); } } diff --git a/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperNorthPane.java b/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperNorthPane.java index 55bb6edd58..1858efb5b5 100644 --- a/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperNorthPane.java +++ b/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperNorthPane.java @@ -372,14 +372,14 @@ public class ReportletHyperNorthPane extends AbstractHyperNorthPane dialogComponents) {// 对话框大小 final JPanel sizePane = new JPanel(new BorderLayout()); UILabel heightLabel = new UILabel(Toolkit.i18nText("Fine-Design_Chart_Height")); - UISpinner heightTextFiled = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_H_VALUE); - this.setHeightTextFiled(heightTextFiled); + UISpinner heightSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_H_VALUE); + this.setHeightSpinner(heightSpinner); UILabel widthLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Designer_Width")); - UISpinner widthTextFiled = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_V_VALUE); - this.setWidthTextFiled(widthTextFiled); + UISpinner widthSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DEFAULT_V_VALUE); + this.setWidthSpinner(widthSpinner); sizePane.add(column(10, - row(4, cell(heightLabel).weight(0.15), cell(heightTextFiled).weight(0.85)), - row(4, cell(widthLabel).weight(0.15), cell(widthTextFiled).weight(0.85)) + row(4, cell(heightLabel).weight(0.15), cell(heightSpinner).weight(0.85)), + row(4, cell(widthLabel).weight(0.15), cell(widthSpinner).weight(0.85)) ).getComponent()); sizePane.setVisible(true); dialogComponents.add(new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Dialog_Size")), sizePane}); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index 8d71ae353f..c2eb76b6e6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java @@ -773,6 +773,22 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta TableDataTreePane.getInstanceWithoutRefreshEverytime(DesignModelAdapter.getCurrentModelAdapter()).resetAddMenuDef(); } + /** + * 报表运行环境改变时,需要刷新某些面板 + */ + public void refreshAfterEnvChange() { + // 设置工作环境标题 + this.setTitle(); + // 刷新模板树操作工具栏 + DesignerFrameFileDealerPane.getInstance().refreshFileActionToolbar(); + // 刷新模板树 + TemplateTreePane.getInstance().refreshDockingView(); + // 刷新模板锁定状态 + DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(null); + // 刷新数据集菜单(远程有数据中心的入口) + TableDataTreePane.getInstanceWithoutRefreshEverytime(DesignModelAdapter.getCurrentModelAdapter()).resetAddMenuDef(); + } + /** * 安装设计器相关插件时的刷新 */ @@ -780,7 +796,6 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta this.setTitle(); TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); DesignTableDataManager.clearGlobalDs(); - EastRegionContainerPane.getInstance().refreshDownPane(); JTemplate template = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); if (template != null) { template.refreshToolArea(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java index 3f6b7ba578..0c194f660a 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java @@ -297,6 +297,14 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt * 刷新菜单 */ public void refreshDockingView() { + refreshFileActionToolbar(); + refresh(); + } + + /** + * 刷新模板目录树操作工具栏 + */ + public void refreshFileActionToolbar() { ToolBarDef toolbarDef = new ToolBarDef(); toolbarDef.addShortCut(newFolderAction, refreshTreeAction); if (WorkContext.getCurrent().isLocal()) { @@ -311,7 +319,6 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt toolbarDef.addShortCut(locateAction, collapseAllAction, switchAction); toolbarDef.updateToolBar(toolBar); resetActionStatus(); - refresh(); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java index 1f635991db..7003008e2e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java @@ -690,9 +690,6 @@ public class EastRegionContainerPane extends UIEastResizableContainer { } } - public void refreshDownPane() { - } - private void refreshContainer() { SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java index 082faf09fd..b2c9e0ae49 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java @@ -29,6 +29,7 @@ import com.fr.workspace.Workspace; import com.fr.workspace.WorkspaceEvent; import com.fr.workspace.server.entity.vcs.VcsBean; import com.fr.workspace.server.entity.vcs.VcsQuery; +import com.fr.workspace.server.repository.WorkplaceConstants; import com.fr.workspace.server.repository.vcs.VcsRepository; import com.fr.workspace.server.vcs.VcsFileUtils; import com.fr.workspace.server.vcs.VcsOperator; @@ -96,7 +97,7 @@ public class VcsHelper implements JTemplateActionListener { @Override protected void on(Event event) { try { - legacyMode = VcsRepository.getInstance().isLegacyMode(); + legacyMode = WorkplaceConstants.isLegacyMode(); FineLoggerFactory.getLogger().info("[VcsHelper] legacyMode:{}", legacyMode); } catch (Exception e) { //保险起见走老逻辑 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 index b7f23374ff..f9312ac077 100644 --- 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 @@ -98,12 +98,15 @@ public class UIUtil { *

* 该方法将执行一个耗时的后台任务,并在任务完成后将结果传递给一个回调函数来更新UI。 * 使用 SwingWorker 来处理后台任务,确保在任务完成后回到 EDT(事件分发线程) 更新 UI。 + * 提供了一个可选的 `finallyBlock` 参数,用于执行清理操作,例如释放资源或重置状态。 * * @param 任务结果的类型 * @param task 需要在后台执行的任务。该任务的执行过程由 Supplier 提供,返回任务的结果。 * @param uiUpdater 在任务完成后执行的回调函数,用来处理结果并更新UI。 + * @param finallyBlock 可选的清理操作,在任务结束后无论是否发生异常都会执行。可以传入 null 表示不需要清理操作。常见场景包括状态标志的重置或资源释放。 + * */ - public static void executeAsyncTaskAndUpdateUI(Supplier task, Consumer uiUpdater) { + public static void executeAsyncTaskAndUpdateUI(Supplier task, Consumer uiUpdater, Runnable finallyBlock) { new SwingWorker() { @Override protected T doInBackground() throws Exception { @@ -116,8 +119,26 @@ public class UIUtil { uiUpdater.accept(result); } catch (InterruptedException | ExecutionException e) { FineLoggerFactory.getLogger().debug(e.getMessage(), e); + } finally { + if (finallyBlock != null) { + finallyBlock.run(); + } } } }.execute(); } + + /** + * 执行异步任务并在任务完成后更新UI。 + *

+ * 该方法将执行一个耗时的后台任务,并在任务完成后将结果传递给一个回调函数来更新UI。 + * 使用 SwingWorker 来处理后台任务,确保在任务完成后回到 EDT(事件分发线程) 更新 UI。 + * + * @param 任务结果的类型 + * @param task 需要在后台执行的任务。该任务的执行过程由 Supplier 提供,返回任务的结果。 + * @param uiUpdater 在任务完成后执行的回调函数,用来处理结果并更新UI。 + */ + public static void executeAsyncTaskAndUpdateUI(Supplier task, Consumer uiUpdater) { + executeAsyncTaskAndUpdateUI(task, uiUpdater, null); + } } diff --git a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java index 91dcb2f902..f9cc6ef703 100644 --- a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java @@ -309,6 +309,17 @@ public class DesignUtils { }); } + /** + * 切换环境后刷新 + */ + public static void refreshDesignerFrameAfterEnvChange() { + if (DesignerContext.getDesignerFrame() == null) { + return; + } + DesignerContext.getDesignerFrame().refreshAfterEnvChange(); + DesignerContext.getDesignerFrame().repaint(); + } + /** * p:初始化look and feel, 把一切放到这个里面.可以让多个地方调用. */ diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index ade89dbf93..9718c5fe30 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -1,6 +1,6 @@ package com.fr.file; -import com.fr.workspace.server.repository.system.WorkspaceSystemInfo; +import com.fr.workspace.server.repository.WorkplaceConstants; import com.fine.theme.icon.LazyIcon; import com.fine.theme.utils.FineComponentsFactory; import com.fine.theme.utils.FineLayoutBuilder; @@ -1663,7 +1663,7 @@ public class FILEChooserPane extends BasicPane { if (!path.endsWith("/") && !path.endsWith("\\") && !StringUtils.isBlank(path)) { path = path + "/"; } - String webAppName = WorkspaceSystemInfo.getINSTANCE().getAppName(); + String webAppName = WorkplaceConstants.getAppName(); if (StringUtils.isBlank(path) && isWebAppNamePath) { this.buttonList.add(createBlankButton(new SetDirectoryAction(webAppName + '/'))); } diff --git a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java index 168a3c315a..472a3fd783 100644 --- a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java +++ b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java @@ -9,9 +9,6 @@ import com.fr.design.file.NodeAuthProcessor; import com.fr.design.gui.itree.filetree.FileNodeComparator; import com.fr.design.gui.itree.filetree.FileTreeIcon; import com.fr.design.i18n.Toolkit; -import com.fr.event.Event; -import com.fr.event.EventDispatcher; -import com.fr.event.Listener; import com.fr.file.filetree.FileNode; import com.fr.general.ComparatorUtils; import com.fr.io.EncryptUtils; @@ -20,11 +17,9 @@ import com.fr.stable.CoreConstants; import com.fr.stable.StableUtils; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; -import com.fr.workspace.Workspace; -import com.fr.workspace.WorkspaceEvent; import com.fr.workspace.server.entity.WorkResourceTempRenameStream; import com.fanruan.entity.template.TemplateListBean; -import com.fr.workspace.server.repository.system.WorkspaceSystemInfo; +import com.fr.workspace.server.repository.WorkplaceConstants; import com.fanruan.repository.TemplateRepository; import javax.swing.*; @@ -35,20 +30,17 @@ import java.util.Arrays; public class FileNodeFILE implements FILE { - public static String webRootPath = WorkspaceSystemInfo.getINSTANCE().getWebRootPath(); - private static String[] supportTypes = TemplateRepository.getInstance().getSupportedTypes(); + public static String webRootPath = WorkplaceConstants.getWebRootPath(); + public static String[] supportTypes = TemplateRepository.getInstance().getSupportedTypes(); - static { - EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener() { - @Override - public void on(Event event, Workspace workspace) { - webRootPath = WorkspaceSystemInfo.getINSTANCE().getWebRootPath(); - supportTypes = TemplateRepository.getInstance().getSupportedTypes(); - } - }); + /** + * 环境切换时更新下 + */ + public static void updateFileInfo() { + webRootPath = WorkplaceConstants.getWebRootPath(); + supportTypes = WorkplaceConstants.getSupportTypes(); } - protected FileNode node; //记录下FILE对应的运行环境,每次创建都设置下当前的运行环境 @@ -382,9 +374,9 @@ public class FileNodeFILE implements FILE { } InputStream in = TemplateResourceManager.getResource().readTemplate( StableUtils.pathJoin( - ProjectConstants.REPORTLETS_NAME, - envPath.substring(ProjectConstants.REPORTLETS_NAME.length() + 1) - )); + ProjectConstants.REPORTLETS_NAME, + envPath.substring(ProjectConstants.REPORTLETS_NAME.length() + 1) + )); return envPath.endsWith(".cpt") || envPath.endsWith(".frm") ? XMLEncryptUtils.decodeInputStream(EncryptUtils.decodeInputStream(FineEncryptUtils.decode(in))) : in; diff --git a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvChooseComponent.java b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvChooseComponent.java index cfc29edad3..62df7c0705 100644 --- a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvChooseComponent.java +++ b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvChooseComponent.java @@ -30,6 +30,7 @@ import com.fr.env.utils.WorkspaceUtils; import com.fr.event.Event; import com.fr.event.Listener; import com.fr.event.Null; +import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNodes; import com.fr.form.share.ShareComponentOperator; import com.fr.form.share.ShareEmbeddedConverter; @@ -118,9 +119,9 @@ public class DesignEnvChooseComponent extends ResourceAffiliate { @Override public void on(Event event, Workspace current) { try { + WorkplaceConstants.updateWorkplaceInfoBean(); + FileNodeFILE.updateFileInfo(); BootstrapFactory.get().reboot("design_env_prepare"); - // 环境切换后,等到模块重启更新一下当前的系统信息 - WorkplaceConstants.updateBean(); recordModuleStartStop(); } catch (Exception e) { throw new RuntimeException(e); @@ -150,7 +151,6 @@ public class DesignEnvChooseComponent extends ResourceAffiliate { @Override public void on(Event event, Workspace workspace) { - HistoryTemplateListCache.getInstance().load(); PluginClassRefreshManager.getInstance().addPluginListener(); } }; diff --git a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java index 107c759bbb..e16a870c55 100644 --- a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java +++ b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java @@ -12,6 +12,9 @@ import com.fanruan.carina.annotions.Stop; import com.fanruan.carina.annotions.Supplemental; import com.fanruan.config.ConfigProviderFactory; import com.fanruan.config.LocalConfigSource; +import com.fr.base.ChartPreStyleConfig; +import com.fr.base.CustomConfig; +import com.fr.base.theme.ReportThemeConfig; import com.fr.env.SetupDataDesignerRemoteOperator; import com.fanruan.config.realm.ConfigRealm; import com.fanruan.dao.context.DBContextProvider; @@ -58,6 +61,8 @@ import com.fr.decision.service.context.ServiceContext; import com.fr.design.backup.EnvBackupHelper; import com.fr.env.detect.EnvDetectorCenter; import com.fr.event.EventDispatcher; +import com.fr.file.ProcedureConfig; +import com.fr.form.ui.WidgetInfoConfig; import com.fr.general.FRLogger; import com.fr.general.log.Log4jConfig; import com.fr.general.log.Log4jConfigFactory; @@ -106,6 +111,8 @@ import com.fr.workspace.WorkContext; import java.sql.Connection; import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; import java.util.Properties; /** @@ -346,6 +353,8 @@ public class DesignEnvComponent { DaoContext.setClassHelperDao(new RemoteClassHelperDao()); DaoContext.setEntityDao(new RemoteEntityDao()); SetupDataHelper.getInstance().registerOperator(SetupDataDesignerRemoteOperator.getInstance()); + //获取需要的配置,避免重复请求 + fetchRemoteConfigs(); } else { //本地 TransactorFactory.setTransactor(new HibernateTransactor()); @@ -362,6 +371,17 @@ public class DesignEnvComponent { InsecurityElementFactory.setConfigInsecurityElementProvider(ConfigInsecurityElementProviderImpl.INSTANCE); } + private void fetchRemoteConfigs() { + List namespaces = Arrays.asList( + Log4jConfig.getInstance().getNameSpace(), + ChartPreStyleConfig.getInstance().getNameSpace(), + ReportThemeConfig.getInstance().getNameSpace(), + CustomConfig.getInstance().getNameSpace(), + WidgetInfoConfig.getInstance().getNameSpace(), + ProcedureConfig.getInstance().getNameSpace() + ); + SetupDataDesignerRemoteOperator.getInstance().fetchBatchConfDatas(namespaces); + } private void stopConfConfig() { SetupDataHelper.getInstance().resetOperator(); diff --git a/designer-realize/src/main/java/com/fanruan/boot/env/function/DesignReportBaseComponent.java b/designer-realize/src/main/java/com/fanruan/boot/env/function/DesignReportBaseComponent.java index c2ff0f85b2..3475b46bac 100644 --- a/designer-realize/src/main/java/com/fanruan/boot/env/function/DesignReportBaseComponent.java +++ b/designer-realize/src/main/java/com/fanruan/boot/env/function/DesignReportBaseComponent.java @@ -6,9 +6,14 @@ import com.fanruan.carina.annotions.FineComponent; import com.fanruan.carina.annotions.Start; import com.fanruan.carina.annotions.Stop; import com.fanruan.carina.annotions.Supplemental; +import com.fr.concurrent.NamedThreadFactory; import com.fr.nx.app.web.StreamAndTemplateReportletCreator; import com.fr.nx.app.web.StreamReportletCreator; +import com.fr.report.ReportHelper; +import com.fr.stable.TemplateIOErrorContextHolder; import com.fr.web.factory.WebletFactory; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; /** * DesignReportBaseComponent @@ -20,6 +25,7 @@ import com.fr.web.factory.WebletFactory; @FineComponent(name = "design_function_report_base") @DependsOn(dependencies = "design_function_chart_base") public class DesignReportBaseComponent extends ReportBaseComponent { + private static final ExecutorService executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("RegisterPluginNameMap")); /** * prepare @@ -45,4 +51,14 @@ public class DesignReportBaseComponent extends ReportBaseComponent { public void stop() { super.stop(); } + + @Override + public void registerPluginNameMap() { + executorService.submit(() -> { + // 插件名称对照表注入 + TemplateIOErrorContextHolder.registerPluginNameMap( + ReportHelper.getPluginNameMap(), + ReportHelper.getPluginNameMapWhitelist()); + }); + } } diff --git a/designer-realize/src/main/java/com/fanruan/boot/init/DesignWorkContextComponent.java b/designer-realize/src/main/java/com/fanruan/boot/init/DesignWorkContextComponent.java index aadc05ce1c..3a54a73f6d 100644 --- a/designer-realize/src/main/java/com/fanruan/boot/init/DesignWorkContextComponent.java +++ b/designer-realize/src/main/java/com/fanruan/boot/init/DesignWorkContextComponent.java @@ -72,6 +72,7 @@ import com.fr.workspace.server.repository.system.SystemInfoRepository; import com.fr.workspace.server.repository.tabledata.TableDataRepository; import com.fr.workspace.server.repository.vcs.VcsRepository; import com.fr.workspace.server.repository.widget.ShareRepository; +import com.fr.workspace.server.repository.workplace.WorkplaceInfoRepository; /** * 设计器工作空间构建模块 @@ -108,6 +109,7 @@ public class DesignWorkContextComponent { RepositoryManager.getInstance().pureRegisterRepo4Start(RemoteAuthorityRepository.getInstance()); RepositoryManager.getInstance().pureRegisterRepo4Start(RemoteNetworkRepository.getInstance()); RepositoryManager.getInstance().pureRegisterRepo4Start(SystemInfoRepository.getInstance()); + RepositoryManager.getInstance().pureRegisterRepo4Start(WorkplaceInfoRepository.getInstance()); RepositoryManager.getInstance().pureRegisterRepo4Start(TableDataRepository.getInstance()); RepositoryManager.getInstance().pureRegisterRepo4Start(TemplateRepository.getInstance()); RepositoryManager.getInstance().pureRegisterRepo4Start(VcsRepository.getInstance()); diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index 18d1aab0a4..17595c25bb 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -22,7 +22,6 @@ 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; @@ -339,14 +338,14 @@ public class MainDesigner extends BaseDesigner { private UICombinationButton createRunButton() { run = new UICombinationButton(new UIButton(Toolkit.i18nText("Fine-Design_Basic_Preview"), new LazyIcon("run").white()), new UIButton(new LazyIcon("triangle_down").white())); - run.addLeftClickLister(mouseEvent -> { + run.addLeftActionListener(event -> { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (jt == null || jt.isSaving()) { return; } WebPreviewUtils.preview(jt); }); - run.addRightClickLister(mouseEvent -> { + run.addRightActionListener(event -> { final JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (jt == null) { return;