1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package ohos.devtools.views.common.treetable; 17 18 import com.intellij.ui.JBColor; 19 import com.intellij.ui.OnePixelSplitter; 20 import com.intellij.ui.components.JBTreeTable; 21 import com.intellij.ui.treeStructure.treetable.TreeTableModel; 22 import ohos.devtools.views.layout.chartview.memory.heapdump.HeapDumpThirdInfo; 23 import org.apache.logging.log4j.LogManager; 24 import org.apache.logging.log4j.Logger; 25 import org.jetbrains.annotations.NotNull; 26 27 import javax.swing.JScrollBar; 28 import javax.swing.JScrollPane; 29 import javax.swing.event.TreeExpansionEvent; 30 import javax.swing.event.TreeExpansionListener; 31 import javax.swing.tree.DefaultMutableTreeNode; 32 import javax.swing.tree.TreePath; 33 import java.awt.Component; 34 import java.util.Vector; 35 36 /** 37 * ExpandTreeTable 38 * 39 * @since 2021/5/19 16:39 40 */ 41 public class ExpandTreeTable extends JBTreeTable { 42 private static final Logger LOGGER = LogManager.getLogger(ExpandTreeTable.class); 43 44 private final Vector<TreePath> expandList = new Vector<>(); 45 private final Vector<Integer> expandRowList = new Vector<>(); 46 private long firstTime; 47 private JScrollBar verticalScrollBar; 48 private int count = 100; 49 private int nextIndex = 0; 50 51 /** 52 * ExpandTreeTable 53 * 54 * @param model model 55 */ ExpandTreeTable(@otNull TreeTableModel model)56 public ExpandTreeTable(@NotNull TreeTableModel model) { 57 super(model); 58 this.getTree().setBackground(JBColor.background()); 59 Component[] components = super.getComponents(); 60 for (Component component : components) { 61 if (component instanceof OnePixelSplitter) { 62 OnePixelSplitter splitter = (OnePixelSplitter) component; 63 JScrollPane firstComponent = null; 64 Object componentObject = splitter.getFirstComponent(); 65 if (componentObject instanceof JScrollPane) { 66 firstComponent = (JScrollPane) componentObject; 67 verticalScrollBar = firstComponent.getVerticalScrollBar(); 68 } 69 } 70 } 71 getTree().addTreeExpansionListener(new TreeExpansionListener() { 72 @Override 73 public void treeExpanded(TreeExpansionEvent event) { 74 if (event.getPath() != null && !expandList.contains(event.getPath())) { 75 expandList.add(event.getPath()); 76 } 77 if (event.getPath() != null && !expandRowList.contains(getTree().getRowForPath(event.getPath()))) { 78 expandRowList.add(getTree().getRowForPath(event.getPath())); 79 } 80 } 81 82 @Override 83 public void treeCollapsed(TreeExpansionEvent event) { 84 if (event.getPath() != null && expandList.contains(event.getPath())) { 85 expandList.remove(event.getPath()); 86 } 87 if (event.getPath() != null && expandRowList.contains(getTree().getRowForPath(event.getPath()))) { 88 Object rowForPathObject = getTree().getRowForPath(event.getPath()); 89 if (rowForPathObject instanceof Integer) { 90 expandRowList.remove((Integer) rowForPathObject); 91 } 92 } 93 loadNodeCollapse(event); 94 } 95 }); 96 } 97 getVerticalScrollBar()98 public JScrollBar getVerticalScrollBar() { 99 return verticalScrollBar; 100 } 101 102 /** 103 * freshTreeExpand 104 */ freshTreeExpand()105 public void freshTreeExpand() { 106 // Two executions are not allowed within 200 ms 107 firstTime = System.currentTimeMillis(); 108 expandList.forEach(item -> { 109 if (!getTree().isExpanded(item)) { 110 getTree().expandPath(item); 111 } 112 }); 113 } 114 115 /** 116 * freshTreeRowExpand 117 */ freshTreeRowExpand()118 public void freshTreeRowExpand() { 119 expandRowList.forEach(item -> { 120 getTree().expandRow(item); 121 }); 122 } 123 124 /** 125 * setTreeTableModel 126 * 127 * @param treeTableModel treeTableModel 128 */ setTreeTableModel(TreeTableModel treeTableModel)129 public void setTreeTableModel(TreeTableModel treeTableModel) { 130 super.setModel(treeTableModel); 131 expandList.clear(); 132 getTree().addTreeExpansionListener(new TreeExpansionListener() { 133 @Override 134 public void treeExpanded(TreeExpansionEvent event) { 135 if (event.getPath() != null && !expandList.contains(event.getPath())) { 136 expandList.add(event.getPath()); 137 } 138 } 139 140 @Override 141 public void treeCollapsed(TreeExpansionEvent event) { 142 if (event.getPath() != null) { 143 expandList.remove(event.getPath()); 144 } 145 } 146 }); 147 } 148 149 /** 150 * loadNodeCollapse 151 * 152 * @param event event 153 */ loadNodeCollapse(TreeExpansionEvent event)154 private void loadNodeCollapse(TreeExpansionEvent event) { 155 DefaultMutableTreeNode currentNode = null; 156 Object lastPathComponentObject = event.getPath().getLastPathComponent(); 157 if (lastPathComponentObject instanceof DefaultMutableTreeNode) { 158 currentNode = (DefaultMutableTreeNode) lastPathComponentObject; 159 Object userObj = currentNode.getUserObject(); 160 if (!(userObj instanceof HeapDumpThirdInfo)) { 161 return; 162 } 163 currentNode.removeAllChildren(); 164 // add None to proved node can expand 165 currentNode.add(new DefaultMutableTreeNode()); 166 count = 0; 167 } 168 } 169 } 170