Browse Source

Pull request #2717: REPORT-40027 缓存模板的组件树展开路径,在切换模板的时候保证组件树的展开

Merge in DESIGN/design from ~YUAN.WANG/design:release/10.0 to release/10.0

* commit 'f40e87fcba78af38409d3f57a2652c054087d731':
  REPORT-40027 NPE
  REPORT-40027 代码修改
  REPORT-40027 缓存模板的组件树展开路径,在切换模板的时候保证组件树的展开
feature/big-screen
Yuan.Wang 4 years ago
parent
commit
1de9b8b925
  1. 22
      designer-base/src/main/java/com/fr/design/mainframe/JTemplateActionListenerAdapter.java
  2. 103
      designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java
  3. 80
      designer-form/src/main/java/com/fr/design/mainframe/FormHierarchyTreePane.java
  4. 12
      designer-form/src/main/java/com/fr/design/mainframe/JForm.java

22
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) {
}
}

103
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<String, List<TreePath>> 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<TreePath> searchList) {
getExpandNodes((XLayoutContainer)designer.getTopContainer(),searchList);
* 从缓存中获取展开路径并进行展开
*/
public void expandTree() {
expandTree(loadTreePath());
}
public void getExpandNodes(XLayoutContainer container, List<TreePath> 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<TreePath> 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<TreePath> 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<TreePath> getExpandTreePaths() {
List<TreePath> result = new ArrayList<>();
TreePath rootTreePath = buildTreePath(designer.getTopContainer());
Enumeration<TreePath> 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<TreePath> 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) {

80
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<TreePath> 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<ShortCut4JControlPane> 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<ShortCut4JControlPane> 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;

12
designer-form/src/main/java/com/fr/design/mainframe/JForm.java

@ -307,6 +307,16 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
}
}
});
addJTemplateActionListener(new JTemplateActionListenerAdapter() {
@Override
public void templateClosed(JTemplate<?, ?> jt) {
if (jt == null) {
return;
}
String key = jt.getEditingFILE().getPath() + jt.getTarget().getTemplateID();
FormHierarchyTreePane.getInstance().removeTreePath(key);
}
});
return tabCenterPane;
}
@ -998,7 +1008,7 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
return ViewRequestConstants.FORM_VIEW_PATH;
}
protected void addChooseFILEFilter(FILEChooserPane fileChooser){
protected void addChooseFILEFilter(FILEChooserPane fileChooser) {
String appName = ProductConstants.APP_NAME;
// richer:form文件 daniel 改成三个字
fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.FRM, appName + Toolkit.i18nText("Fine-Design_Report_Template_File")));

Loading…
Cancel
Save