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 ce495cdb9..382709c92 100644
--- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
+++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
@@ -5,6 +5,7 @@ import com.fr.design.data.DesignTableDataManager;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
+import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.env.DesignerWorkspaceGenerator;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceType;
@@ -18,7 +19,10 @@ import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.DesignUtils;
import com.fr.env.CheckServiceDialog;
import com.fr.env.EnvListPane;
+import com.fr.env.RemoteWorkspaceURL;
+import com.fr.env.TestConnectionResult;
import com.fr.exit.DesignerExiter;
+import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
import com.fr.invoke.Reflect;
import com.fr.json.JSONArray;
@@ -40,6 +44,7 @@ import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.base.FineObjectPool;
import com.fr.workspace.engine.channel.http.FunctionalHttpRequest;
import com.fr.workspace.engine.exception.WorkspaceAuthException;
+import com.fr.workspace.engine.exception.WorkspaceCheckException;
import com.fr.workspace.engine.exception.WorkspaceConnectionException;
import com.fr.workspace.engine.rpc.WorkspaceProxyPool;
@@ -145,21 +150,28 @@ public class EnvChangeEntrance {
strategy.showTip(new PopTip() {
@Override
public void show() {
- FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"),
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"));
+ FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),
+ Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"),
+ Toolkit.i18nText("Fine-Design_Basic_Error"),
+ ERROR_MESSAGE,
+ UIManager.getIcon("OptionPane.errorIcon"));
}
});
return false;
+ } catch (WorkspaceCheckException e) {
+ handleWorkspaceCheckException(e, strategy, connectionInfo);
+ return false;
} catch (Exception exception) {
- FineLoggerFactory.getLogger().error(exception.getMessage(), exception);
- strategy.showTip(new PopTip() {
- @Override
- public void show() {
- FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"),
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"));
- }
- });
-
+ if (exception.getCause() instanceof WorkspaceCheckException) {
+ handleWorkspaceCheckException((WorkspaceCheckException) exception.getCause(), strategy, connectionInfo);
+ } else {
+ FineLoggerFactory.getLogger().error(exception.getMessage(), exception);
+ strategy.showTip(() -> FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),
+ Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"),
+ Toolkit.i18nText("Fine-Design_Basic_Error"),
+ ERROR_MESSAGE,
+ UIManager.getIcon("OptionPane.errorIcon")));
+ }
return false;
}
TemplateTreePane.getInstance().refreshDockingView();
@@ -170,6 +182,24 @@ public class EnvChangeEntrance {
return true;
}
+ private void handleWorkspaceCheckException(WorkspaceCheckException e, PopTipStrategy strategy, WorkspaceConnectionInfo info) {
+ TestConnectionResult result = TestConnectionResult.parseByException(e);
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ if (ComparatorUtils.equals(result, TestConnectionResult.AUTH_FAILED)) {
+ strategy.showTip(() -> FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),
+ Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"),
+ Toolkit.i18nText("Fine-Design_Basic_Error"),
+ ERROR_MESSAGE,
+ UIManager.getIcon("OptionPane.errorIcon")));
+ } else {
+ strategy.showTip(() -> FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),
+ new MessageWithLink(result.getText(), Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Modify_PassWord"), info.getUrl() + RemoteWorkspaceURL.SYSTEM_LOGIN_PATH),
+ Toolkit.i18nText("Fine-Design_Basic_Error"),
+ ERROR_MESSAGE,
+ UIManager.getIcon("OptionPane.errorIcon")));
+ }
+ }
+
/**
* 这个功能留着,可能会加回来,先做注释处理
* 切换远程环境之前,进行版本检测,当版本不一致的时候,提示。
diff --git a/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java
new file mode 100644
index 000000000..8a1f55cbd
--- /dev/null
+++ b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java
@@ -0,0 +1,55 @@
+package com.fr.design.dialog.link;
+
+import com.fr.design.gui.ilable.UILabel;
+import com.fr.log.FineLoggerFactory;
+import com.fr.stable.StringUtils;
+import java.awt.Color;
+import java.awt.Desktop;
+import java.awt.Font;
+import java.net.URI;
+import javax.swing.JEditorPane;
+import javax.swing.event.HyperlinkEvent;
+
+/**
+ * 用来构建JOptionPane带超链的消息提示
+ *
+ * @author hades
+ * @version 10.0
+ * Created by hades on 2020/10/23
+ */
+public class MessageWithLink extends JEditorPane {
+
+ public MessageWithLink(String message, String linkName, String link) {
+ super("text/html", "
" + message + "" + linkName + "" + "");
+ addHyperlinkListener(e -> {
+ if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
+ try {
+ Desktop.getDesktop().browse(URI.create(link));
+ } catch (Exception exception) {
+ FineLoggerFactory.getLogger().error(exception.getMessage(), exception);
+ }
+ }
+ });
+ setEditable(false);
+ setBorder(null);
+ }
+
+ public MessageWithLink(String linkName, String link ) {
+ this(StringUtils.EMPTY, linkName, link);
+ }
+
+ private static StringBuilder getStyle() {
+ // 构建和相同风格样式
+ UILabel label = new UILabel();
+ Font font = label.getFont();
+ Color color = label.getBackground();
+
+ StringBuilder style = new StringBuilder("font-family:" + font.getFamily() + ";");
+ style.append("font-weight:").append(font.isBold() ? "bold" : "normal").append(";");
+ style.append("font-size:").append(font.getSize()).append("pt;");
+ style.append("background-color: rgb(").append(color.getRed()).append(",").append(color.getGreen()).append(",").append(color.getBlue()).append(");");
+
+ return style;
+ }
+
+}
diff --git a/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java b/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java
index 37a671eeb..f9de1cfa4 100644
--- a/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java
+++ b/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java
@@ -169,7 +169,8 @@ public class RemoteDesignerWorkspaceInfo implements DesignerWorkspaceInfo {
return result;
}
try {
- result = WorkContext.getConnector().testConnection(connection);
+ WorkContext.getConnector().validateVT(connection);
+ result = true;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return result;
diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplateActionListenerAdapter.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateActionListenerAdapter.java
new file mode 100644
index 000000000..7065f3e94
--- /dev/null
+++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateActionListenerAdapter.java
@@ -0,0 +1,22 @@
+package com.fr.design.mainframe;
+
+/**
+ * @Author: Yuan.Wang
+ * @Date: 2020/10/27
+ */
+public class JTemplateActionListenerAdapter implements JTemplateActionListener {
+ @Override
+ public void templateOpened(JTemplate, ?> jt) {
+
+ }
+
+ @Override
+ public void templateSaved(JTemplate, ?> jt) {
+
+ }
+
+ @Override
+ public void templateClosed(JTemplate, ?> jt) {
+
+ }
+}
diff --git a/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java b/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java
index 5257e74f4..0b7d64ee1 100644
--- a/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java
+++ b/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java
@@ -4,6 +4,8 @@ import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.border.UITitledBorder;
+import com.fr.design.dialog.FineJOptionPane;
+import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.env.RemoteDesignerWorkspaceInfo;
import com.fr.design.fun.DesignerEnvProcessor;
import com.fr.design.gui.ibutton.UIButton;
@@ -16,6 +18,7 @@ import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
+import com.fr.design.mainframe.DesignerContext;
import com.fr.design.scrollruler.ModLineBorder;
import com.fr.license.exception.RegistEditionException;
import com.fr.log.FineLoggerFactory;
@@ -25,6 +28,7 @@ import com.fr.workspace.WorkContext;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.exception.WorkspaceAuthException;
+import com.fr.workspace.engine.exception.WorkspaceCheckException;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
@@ -53,12 +57,13 @@ import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
-import java.util.function.Supplier;
+
import static com.fr.design.layout.TableLayout.FILL;
import static com.fr.design.layout.TableLayout.PREFERRED;
import static com.fr.env.TestConnectionResult.AUTH_FAILED;
import static com.fr.third.guava.base.Optional.fromNullable;
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
/**
* @author yaohwu
@@ -583,6 +588,8 @@ public class RemoteEnvPane extends BasicBeanPane {
} catch (RegistEditionException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
throw e;
+ } catch (WorkspaceCheckException e) {
+ return TestConnectionResult.parseByException(e);
}
}
@@ -591,6 +598,14 @@ public class RemoteEnvPane extends BasicBeanPane {
okButton.setEnabled(true);
try {
TestConnectionResult result = get();
+ if (result.isVerifyResult()) {
+ dialog.dispose();
+ FineJOptionPane.showMessageDialog(RemoteEnvPane.this,
+ new MessageWithLink(result.getText(), Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Modify_PassWord"), connection.getUrl() + RemoteWorkspaceURL.SYSTEM_LOGIN_PATH),
+ Toolkit.i18nText("Fine-Design_Basic_Dialog_Message_Title"),
+ ERROR_MESSAGE,
+ UIManager.getIcon("OptionPane.errorIcon"));
+ }
message.setText(result.getText());
uiLabel.setIcon(result.getIcon());
} catch (Exception e) {
@@ -635,7 +650,7 @@ public class RemoteEnvPane extends BasicBeanPane {
message.setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 0));
okButton.setEnabled(false);
- dialog = new JDialog((Dialog) SwingUtilities.getWindowAncestor(RemoteEnvPane.this), UIManager.getString("OptionPane.messageDialogTitle"), true);
+ dialog = new JDialog((Dialog) SwingUtilities.getWindowAncestor(RemoteEnvPane.this), Toolkit.i18nText("Fine-Design_Basic_Dialog_Message_Title"), true);
dialog.setSize(new Dimension(308, 132));
okButton.setEnabled(false);
diff --git a/designer-base/src/main/java/com/fr/env/RemoteWorkspaceURL.java b/designer-base/src/main/java/com/fr/env/RemoteWorkspaceURL.java
index dee40422c..4ea950e84 100644
--- a/designer-base/src/main/java/com/fr/env/RemoteWorkspaceURL.java
+++ b/designer-base/src/main/java/com/fr/env/RemoteWorkspaceURL.java
@@ -9,6 +9,8 @@ import com.fr.stable.StringUtils;
*/
public class RemoteWorkspaceURL implements FCloneable {
+ public static final String SYSTEM_LOGIN_PATH = "#management/system/login";
+
/**
* 默认 web app name
*/
diff --git a/designer-base/src/main/java/com/fr/env/TestConnectionResult.java b/designer-base/src/main/java/com/fr/env/TestConnectionResult.java
index 4524254f4..c44f18487 100644
--- a/designer-base/src/main/java/com/fr/env/TestConnectionResult.java
+++ b/designer-base/src/main/java/com/fr/env/TestConnectionResult.java
@@ -1,12 +1,15 @@
package com.fr.env;
+import com.fr.decision.webservice.exception.login.UserLoginLockException;
+import com.fr.decision.webservice.exception.login.UserPasswordNeedUpdateException;
+import com.fr.decision.webservice.exception.user.UserPasswordStrengthLimitException;
import com.fr.design.i18n.Toolkit;
-import com.fr.log.FineLoggerFactory;
-import com.fr.stable.AssistUtils;
-import com.fr.workspace.WorkContext;
+import com.fr.exception.RemoteDesignPermissionDeniedException;
+import com.fr.general.ComparatorUtils;
+import com.fr.stable.StringUtils;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
-import com.fr.workspace.engine.channel.http.FunctionalHttpRequest;
+import com.fr.workspace.engine.exception.WorkspaceCheckException;
import javax.swing.Icon;
import javax.swing.UIManager;
@@ -76,12 +79,127 @@ public enum TestConnectionResult {
public String getText() {
return Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Auth_Failed");
}
+ },
+
+ /**
+ * 登录锁定
+ */
+ LOGIN_LOCK {
+
+ private String value;
+
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.errorIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Login_Lock", value);
+ }
+
+ @Override
+ public String errorCode() {
+ return UserLoginLockException.ERROR_CODE;
+ }
+
+ @Override
+ public void setValue(String lockMin) {
+ this.value = lockMin;
+ }
+
+ @Override
+ public boolean isVerifyResult() {
+ return true;
+ }
+ },
+
+ /**
+ * 没有远程设计权限
+ */
+ PERMISSION_DENIED {
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.errorIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Permission_Denied");
+ }
+
+ @Override
+ public String errorCode() {
+ return RemoteDesignPermissionDeniedException.ERROR_CODE;
+ }
+ },
+
+ /**
+ * 弱密码
+ */
+ PASSWORD_STRENGTH_LIMIT () {
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.errorIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Weak_Password");
+ }
+
+ @Override
+ public String errorCode() {
+ return UserPasswordStrengthLimitException.ERROR_CODE;
+ }
+
+ @Override
+ public boolean isVerifyResult() {
+ return true;
+ }
+ },
+
+ /**
+ * 密码更新
+ */
+ PASSWORD_NEED_UPDATE {
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.errorIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Update_Password");
+ }
+
+ @Override
+ public String errorCode() {
+ return UserPasswordNeedUpdateException.ERROR_CODE;
+ }
+
+ @Override
+ public boolean isVerifyResult() {
+ return true;
+ }
};
public abstract Icon getIcon();
public abstract String getText();
+ public void setValue(String value) {
+ // do noting
+ }
+
+ public String errorCode() {
+ return StringUtils.EMPTY;
+ }
+
+ public boolean isVerifyResult() {
+ return false;
+ }
+
public static TestConnectionResult parse(Boolean value, WorkspaceConnectionInfo info) {
if (value == null) {
return AUTH_FAILED;
@@ -92,4 +210,17 @@ public enum TestConnectionResult {
//去掉测试连接时所做的检测
return FULLY_SUCCESS;
}
+
+ public static TestConnectionResult parseByException(WorkspaceCheckException e) {
+ for (TestConnectionResult result : values()) {
+ if (ComparatorUtils.equals(e.errorCode(), result.errorCode())) {
+ // 登录锁定 获取下锁定的时间
+ if (ComparatorUtils.equals(result, LOGIN_LOCK)) {
+ result.setValue(e.getMessage().replaceAll("\\D+", StringUtils.EMPTY));
+ }
+ return result;
+ }
+ }
+ return AUTH_FAILED;
+ }
}
diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java
index 24c3a19db..c0eb39297 100644
--- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java
+++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java
@@ -19,7 +19,12 @@ import com.fr.design.designer.creator.cardlayout.XWCardTitleLayout;
import com.fr.design.designer.creator.cardlayout.XWTabFitLayout;
import com.fr.design.designer.properties.FRFitLayoutConstraints;
import com.fr.design.designer.properties.FRFitLayoutPropertiesGroupModel;
+import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.fun.FormWidgetOptionProvider;
+import com.fr.design.mainframe.FormDesigner;
+import com.fr.design.mainframe.JForm;
+import com.fr.design.mainframe.JTemplate;
+import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.container.WAbsoluteLayout;
@@ -342,7 +347,15 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter {
//拖拽组件原大小、位置
Rectangle backupBound = creator.getBackupBound();
backupBound.x -= container.getX();
- backupBound.y -= container.getY();
+ // REPORT-34739 对绝对画布块的backupBound.y的调整还需要考虑一下参数面板块的高度造成的偏移
+ int paraHeight = 0;
+ if (creator.acceptType(XWAbsoluteLayout.class)) {
+ JTemplate, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
+ if (jTemplate instanceof JForm) {
+ paraHeight = ((JForm) jTemplate).getFormDesign().getParaHeight();
+ }
+ }
+ backupBound.y -= (container.getY() - paraHeight);
//当前拖拽组件的位置
int x = creator.getX();
int y = creator.getY();
diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java
index ee667fd38..e1ac304b2 100644
--- a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java
+++ b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java
@@ -4,11 +4,9 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.design.designer.creator.XLayoutContainer;
-import com.fr.design.designer.creator.XWAbsoluteBodyLayout;
-import com.fr.design.designer.creator.XWFitLayout;
-import com.fr.design.designer.creator.cardlayout.XCardSwitchButton;
import com.fr.design.designer.treeview.ComponentTreeCellRenderer;
import com.fr.design.designer.treeview.ComponentTreeModel;
+import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.itree.UITreeUI;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StringUtils;
@@ -19,9 +17,7 @@ import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
-import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellRenderer;
-import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.BorderLayout;
@@ -37,8 +33,9 @@ import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.List;
-import java.util.Vector;
+import java.util.Map;
public class ComponentTree extends JTree {
@@ -46,6 +43,8 @@ public class ComponentTree extends JTree {
private ComponentTreeModel model;
private UITreeUI uiTreeUI = new UITreeUI();
private PopupPreviewPane previewPane;
+
+ private static final Map> treePathCache = new HashMap<>();
private static final int PADDING_LEFT = 5;
private static final int PADDING_TOP = 5;
@@ -85,6 +84,7 @@ public class ComponentTree extends JTree {
public ComponentTree(FormDesigner designer, ComponentTreeModel model) {
this(designer);
this.setModel(model);
+ expandTree();
}
public void setSelectionPath(TreePath path) {
@@ -138,7 +138,6 @@ public class ComponentTree extends JTree {
setSelectionPaths(treepath);
if (treepath.length > 0) {
scrollPathToVisible(treepath[0]);
- //expandPath(treepath[0]);
}
}
@@ -193,6 +192,20 @@ public class ComponentTree extends JTree {
return paths;
}
+ @Override
+ protected void setExpandedState(TreePath path, boolean state) {
+ super.setExpandedState(path, state);
+ saveTreePath();
+ }
+
+ /**
+ * 删除key对应的缓存展开路径
+ */
+ public void removeTreePath(String key) {
+ if (StringUtils.isNotEmpty(key)) {
+ treePathCache.remove(key);
+ }
+ }
private void setSelectionPath() {
@@ -232,6 +245,7 @@ public class ComponentTree extends JTree {
public void refreshTreeRoot() {
model = new ComponentTreeModel(designer, designer.getTopContainer());
setModel(model);
+ expandTree();
setDragEnabled(false);
setDropMode(DropMode.ON_OR_INSERT);
setTransferHandler(new TreeTransferHandler());
@@ -239,49 +253,56 @@ public class ComponentTree extends JTree {
}
/**
- * 获得树的展开路径
- * */
- public void getExpandNodes(List searchList) {
- getExpandNodes((XLayoutContainer)designer.getTopContainer(),searchList);
+ * 从缓存中获取展开路径并进行展开
+ */
+ public void expandTree() {
+ expandTree(loadTreePath());
}
- public void getExpandNodes(XLayoutContainer container, List searchList) {
- TreePath treePath = buildTreePath(container);
- if (isExpanded(treePath)) {
- searchList.add(treePath);
- for (int i = 0, size = container.getXCreatorCount(); i < size; i++) {
- XCreator creator = container.getXCreator(i);
- if (creator.acceptType(XLayoutContainer.class) || creator.acceptType(XCardSwitchButton.class)) {
- getExpandNodes((XLayoutContainer) creator.getXCreator(), searchList);
- }
- }
+ /**
+ * 按照传入参数展开组件树
+ */
+ private void expandTree(List list) {
+ if (list == null) {
+ return;
}
- //对绝对布局做特殊处理
- if (container.acceptType(XWFitLayout.class)) {
- XWFitLayout bodyFitLayout = (XWFitLayout) container;
- for (int j = 0; j < bodyFitLayout.getXCreatorCount(); j++) {
- //类型是绝对布局并且还是body
- if (bodyFitLayout.getXCreator(j).acceptType(XWAbsoluteBodyLayout.class)) {
- container = (XLayoutContainer) bodyFitLayout.getXCreator(j);
- getExpandNodes(container, searchList);
- }
- }
+ for (TreePath treePath : list) {
+ expandPath(treePath);
}
}
/**
- * 将树按照展开路径进行展开
- * */
- public void expandNodes(List list){
- for(TreePath treePath:list) {
- if (treePath.getLastPathComponent() instanceof XLayoutContainer) {
- XLayoutContainer creator= (XLayoutContainer) treePath.getLastPathComponent();
- if (XCreatorUtils.getParentXLayoutContainer(creator) == null) {
- continue;
- }
- expandPath(treePath);
+ * 获得树的展开路径
+ */
+ private List getExpandTreePaths() {
+ List result = new ArrayList<>();
+ TreePath rootTreePath = buildTreePath(designer.getTopContainer());
+ Enumeration enumeration = getExpandedDescendants(rootTreePath);
+ if (enumeration != null) {
+ while (enumeration.hasMoreElements()) {
+ result.add(enumeration.nextElement());
}
}
+ return result;
+ }
+
+ private void saveTreePath() {
+ String templateID = designer.getTarget().getTemplateID();
+ JTemplate, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
+ if (templateID != null && jt != null && StringUtils.equals(templateID, jt.getTarget().getTemplateID())) {
+ String key = jt.getEditingFILE().getPath() + templateID;
+ treePathCache.put(key, getExpandTreePaths());
+ }
+ }
+
+ private List loadTreePath() {
+ JTemplate, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
+ if (jt == null) {
+ return null;
+ }
+ String key = jt.getEditingFILE().getPath() + designer.getTarget().getTemplateID();
+
+ return treePathCache.get(key);
}
private TreePath buildTreePath(Component comp) {
diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormHierarchyTreePane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormHierarchyTreePane.java
index f94475a76..fdb8881c7 100644
--- a/designer-form/src/main/java/com/fr/design/mainframe/FormHierarchyTreePane.java
+++ b/designer-form/src/main/java/com/fr/design/mainframe/FormHierarchyTreePane.java
@@ -4,7 +4,6 @@ import com.fr.base.BaseUtils;
import com.fr.design.actions.UndoableAction;
import com.fr.design.constants.UIConstants;
import com.fr.design.designer.beans.events.DesignerEditListener;
-import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XWAbsoluteBodyLayout;
import com.fr.design.designer.creator.XWParameterLayout;
@@ -24,14 +23,12 @@ import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
-import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
-import java.util.List;
/**
@@ -48,6 +45,10 @@ public class FormHierarchyTreePane extends FormDockView implements HierarchyTree
private ShortCut4JControlPane[] shorts;
private ComponentTree componentTree;
+ private final DesignerEditListener designerEditListener = evt -> {
+ refreshComponentTree();
+ };
+
public static FormHierarchyTreePane getInstance() {
return HOLDER.singleton;
}
@@ -94,10 +95,8 @@ public class FormHierarchyTreePane extends FormDockView implements HierarchyTree
//TODO 太乱了,需要重写,监听器里加了监听器是什么意思,每次调用该方法都会添加一个新的监听器
public void refreshDockingView() {
FormDesigner formDesigner = this.getEditingFormDesigner();
- List list = new ArrayList<>();
removeAll();
if (this.componentTree != null) {
- componentTree.getExpandNodes(list);
this.componentTree.removeAll();
}
if (formDesigner == null) {
@@ -106,13 +105,7 @@ public class FormHierarchyTreePane extends FormDockView implements HierarchyTree
}
componentTree = new ComponentTree(formDesigner);
//保证删除组件后组件树不收起
- componentTree.expandNodes(list);
- formDesigner.addDesignerEditListener(new DesignerEditListener() {
- @Override
- public void fireCreatorModified(DesignerEvent evt) {
- refreshComponentTree();
- }
- });
+ formDesigner.addDesignerEditListener(designerEditListener);
ComponentTreeModel treeModel = (ComponentTreeModel) componentTree.getModel();
XCreator root = (XCreator) treeModel.getRoot();
@@ -128,6 +121,38 @@ public class FormHierarchyTreePane extends FormDockView implements HierarchyTree
refreshComponentTree();
}
+ public void removeTreePath(String key) {
+ componentTree.removeTreePath(key);
+ }
+
+ /**
+ * 刷新树
+ */
+ public void refreshRoot() {
+ componentTree.refreshTreeRoot();
+ }
+
+ @Override
+ /**
+ * 位置
+ *
+ * @return 位置
+ */
+ public Location preferredLocation() {
+ return Location.WEST_BELOW;
+ }
+
+ protected ShortCut4JControlPane[] createShortcuts() {
+ ArrayList shortCutList = new ArrayList<>();
+ FormDesigner designer = getEditingFormDesigner();
+
+ for (Action action : designer.getActions()) {
+ shortCutList.add(new WidgetEnableShortCut((UndoableAction) action));
+ }
+
+ return shortCutList.toArray(new ShortCut4JControlPane[shortCutList.size()]);
+ }
+
private void refreshComponentTree() {
componentTree.setAndScrollSelectionPath(componentTree.getSelectedTreePath());
SwingUtilities.invokeLater(new Runnable() {
@@ -178,17 +203,6 @@ public class FormHierarchyTreePane extends FormDockView implements HierarchyTree
return toolBarPaneWrapper;
}
- protected ShortCut4JControlPane[] createShortcuts() {
- ArrayList shortCutList = new ArrayList<>();
- FormDesigner designer = getEditingFormDesigner();
-
- for (Action action : designer.getActions()) {
- shortCutList.add(new WidgetEnableShortCut((UndoableAction) action));
- }
-
- return shortCutList.toArray(new ShortCut4JControlPane[shortCutList.size()]);
- }
-
/**
* 调整结构树para和body的位置
*
@@ -212,26 +226,6 @@ public class FormHierarchyTreePane extends FormDockView implements HierarchyTree
componentTree = new ComponentTree(formDesigner, treeModel);
}
- /**
- * 刷新树
- */
- public void refreshRoot() {
- if (componentTree == null) {
- return;
- }
- componentTree.refreshTreeRoot();
- }
-
- @Override
- /**
- * 位置
- *
- * @return 位置
- */
- public Location preferredLocation() {
- return Location.WEST_BELOW;
- }
-
private class WidgetEnableShortCut extends ShortCut4JControlPane {
public WidgetEnableShortCut(ShortCut shortCut) {
this.shortCut = shortCut;
diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java
index 7cdd7fd60..b7fb90fcb 100644
--- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java
+++ b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java
@@ -307,6 +307,16 @@ public class JForm extends JTemplate