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.trace.component; 17 18 import com.intellij.ui.components.JBLabel; 19 import com.intellij.ui.components.JBPanel; 20 import com.intellij.ui.components.JBScrollPane; 21 import com.intellij.ui.table.JBTable; 22 import net.miginfocom.swing.MigLayout; 23 import ohos.devtools.views.trace.Sql; 24 import ohos.devtools.views.trace.bean.TraceLog; 25 import ohos.devtools.views.trace.util.Db; 26 import ohos.devtools.views.trace.util.TimeUtils; 27 28 import javax.swing.JViewport; 29 import javax.swing.table.AbstractTableModel; 30 import javax.swing.table.TableColumn; 31 import javax.swing.table.TableColumnModel; 32 import java.awt.Point; 33 import java.awt.Rectangle; 34 import java.awt.event.ComponentAdapter; 35 import java.awt.event.ComponentEvent; 36 import java.time.format.DateTimeFormatter; 37 import java.util.ArrayList; 38 import java.util.List; 39 40 /** 41 * TabLogTable 42 * 43 * @since 2021/04/20 12:12 44 */ 45 public class TabLogTable extends JBPanel { 46 private float[] columnWidthPercentage = {0.15f, 0.05f, 0.2f, 0.6f}; 47 private TableModel model = new TableModel(); 48 private JBTable table = new JBTable(model); 49 private JBLabel label = new JBLabel(); 50 private int count = -1; 51 private int pageSize = 20; 52 private int page = 1; 53 private boolean loading = false; 54 private boolean complete = false; 55 private long endTime; 56 private long startTime; 57 private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 58 59 /** 60 * TabLogTable 61 */ TabLogTable()62 public TabLogTable() { 63 setLayout(new MigLayout("inset 8")); 64 JBScrollPane scrollPane = new JBScrollPane(table); 65 table.setShowGrid(false); 66 table.setRowHeight(40); 67 add(label, "pushx,growx,wrap"); 68 add(scrollPane, "push,grow"); 69 resizeColumns(); 70 addComponentListener(new ComponentAdapter() { 71 @Override 72 public void componentResized(ComponentEvent event) { 73 resizeColumns(); 74 } 75 }); 76 JViewport viewport = scrollPane.getViewport(); 77 scrollPane.getViewport().addChangeListener(event -> { 78 Rectangle viewRect = viewport.getViewRect(); 79 int first = table.rowAtPoint(new Point(0, viewRect.y)); 80 if (first == -1) { 81 return; // Table is empty 82 } 83 int last = table.rowAtPoint(new Point(0, viewRect.y + viewRect.height - 1)); 84 if (last == -1) { 85 last = model.getRowCount() - 1; // Handle empty space below last row 86 } 87 label.setText("Logs rows [" + first + "," + last + "] / " + count + ""); 88 if (last + 1 == page * pageSize) { 89 page++; 90 if (!loading && !complete) { 91 query(page, pageSize); 92 } 93 } 94 }); 95 } 96 resizeColumns()97 private void resizeColumns() { 98 int tableWidth = table.getWidth(); 99 TableColumn column; 100 TableColumnModel jTableColumnModel = table.getColumnModel(); 101 int cantCols = jTableColumnModel.getColumnCount(); 102 for (int index = 0; index < cantCols; index++) { 103 column = jTableColumnModel.getColumn(index); 104 int pWidth = Math.round(columnWidthPercentage[index] * tableWidth); 105 column.setPreferredWidth(pWidth); 106 } 107 } 108 109 /** 110 * query log 111 * 112 * @param clean clean 113 */ query(boolean clean)114 public void query(boolean clean) { 115 loading = true; 116 page = 1; 117 pageSize = 20; 118 List<TraceLog> traceLogs = new ArrayList<>() { 119 }; 120 Db.getInstance().query(Sql.SYS_QUERY_LOGS, traceLogs, startTime, endTime, pageSize, (page - 1) * pageSize); 121 if (clean) { 122 model.dataSource.clear(); 123 } 124 model.dataSource.addAll(traceLogs); 125 model.fireTableDataChanged(); 126 count = Db.getInstance().queryCount(Sql.SYS_QUERY_LOGS_COUNT, startTime, endTime); 127 label.setText("Logs rows [0,20] / " + count + ""); 128 loading = false; 129 } 130 query(Integer page, Integer pageSize)131 private void query(Integer page, Integer pageSize) { 132 loading = true; 133 this.page = page; 134 this.pageSize = pageSize; 135 List<TraceLog> traceLogs = new ArrayList<>() { 136 }; 137 Db.getInstance().query(Sql.SYS_QUERY_LOGS, traceLogs, startTime, endTime, pageSize, (page - 1) * pageSize); 138 if (traceLogs.size() < pageSize) { 139 complete = true; 140 } 141 model.dataSource.addAll(traceLogs); 142 model.fireTableDataChanged(); 143 loading = false; 144 } 145 146 /** 147 * time range change 148 * 149 * @param sn sn 150 * @param en en 151 */ rangeChange(long sn, long en)152 public void rangeChange(long sn, long en) { 153 this.startTime = sn; 154 this.endTime = en; 155 loading = false; 156 complete = false; 157 query(true); 158 } 159 160 private class TableModel extends AbstractTableModel { 161 private List<TraceLog> dataSource = new ArrayList<>(); 162 163 private List<Column> columnNames = new ArrayList<>() { 164 { 165 add(new Column("time", (item) -> TimeUtils.getLogTimeString(item.getStartTime()))); 166 add(new Column("level", (item) -> item.getLevel())); 167 add(new Column("tag", (item) -> item.getTag())); 168 add(new Column("context", (item) -> item.getContext())); 169 } 170 }; 171 172 /** 173 * getRowCount 174 * 175 * @return int 176 */ 177 @Override getRowCount()178 public int getRowCount() { 179 return dataSource.size(); 180 } 181 182 /** 183 * getColumnCount 184 * 185 * @return int 186 */ 187 @Override getColumnCount()188 public int getColumnCount() { 189 return columnNames.size(); 190 } 191 192 /** 193 * getColumnName 194 * 195 * @param column column 196 * @return String 197 */ 198 @Override getColumnName(int column)199 public String getColumnName(int column) { 200 return columnNames.get(column).name; 201 } 202 203 /** 204 * getValueAt 205 * 206 * @param rowIndex rowIndex 207 * @param columnIndex columnIndex 208 * @return Object 209 */ 210 @Override getValueAt(int rowIndex, int columnIndex)211 public Object getValueAt(int rowIndex, int columnIndex) { 212 return columnNames.get(columnIndex).callable.map(dataSource.get(rowIndex)); 213 } 214 215 /** 216 * isCellEditable 217 * 218 * @param rowIndex rowIndex 219 * @param columnIndex columnIndex 220 * @return boolean 221 */ 222 @Override isCellEditable(int rowIndex, int columnIndex)223 public boolean isCellEditable(int rowIndex, int columnIndex) { 224 return columnIndex == columnNames.size() - 1; 225 } 226 227 } 228 229 private class Column { 230 private String name; 231 private Process callable; 232 233 /** 234 * Column 235 * 236 * @param name name 237 * @param callable callable 238 */ Column(String name, Process callable)239 public Column(String name, Process callable) { 240 this.name = name; 241 this.callable = callable; 242 } 243 } 244 245 private interface Process { 246 /** 247 * map 248 * 249 * @param traceLog traceLog 250 * @return Object 251 */ map(TraceLog traceLog)252 Object map(TraceLog traceLog); 253 } 254 } 255