Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
JTablePanel.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2020-2021 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.datasourcesummary.uiutils;
20
21import java.awt.BorderLayout;
22import java.awt.Graphics;
23import java.awt.event.MouseAdapter;
24import java.awt.event.MouseEvent;
25import java.util.Collections;
26import java.util.List;
27import java.util.function.Function;
28import java.util.stream.Collectors;
29import javax.swing.JComponent;
30import javax.swing.JLayer;
31import javax.swing.JScrollPane;
32import javax.swing.JTable;
33import javax.swing.plaf.LayerUI;
34import javax.swing.table.DefaultTableColumnModel;
35import javax.swing.table.TableColumn;
36import javax.swing.table.TableColumnModel;
37
42public class JTablePanel<T> extends AbstractLoadableComponent<List<T>> {
43
44 private static final int EXTRA_ROW_HEIGHT = 4;
45
50 public static class CellMouseEvent {
51
52 private final MouseEvent e;
53 private final JTable table;
54 private final int row;
55 private final int col;
56 private final Object cellValue;
57
67 public CellMouseEvent(MouseEvent e, JTable table, int row, int col, Object cellValue) {
68 this.e = e;
69 this.table = table;
70 this.row = row;
71 this.col = col;
72 this.cellValue = cellValue;
73 }
74
78 public MouseEvent getMouseEvent() {
79 return e;
80 }
81
85 public JTable getTable() {
86 return table;
87 }
88
92 public int getRow() {
93 return row;
94 }
95
99 public int getCol() {
100 return col;
101 }
102
106 public Object getCellValue() {
107 return cellValue;
108 }
109 }
110
114 public interface CellMouseListener {
115
123 }
124
130 private static class Overlay extends LayerUI<JComponent> {
131
132 private static final long serialVersionUID = 1L;
134
141 void setVisible(boolean visible) {
142 overlayDelegate.setVisible(visible);
143 }
144
150 void setMessage(String message) {
152 }
153
154 @Override
155 public void paint(Graphics g, JComponent c) {
156 super.paint(g, c);
157 overlayDelegate.paintOverlay(g, c.getWidth(), c.getHeight());
158 }
159 }
160
161 private static final long serialVersionUID = 1L;
162
164
172 public static <T, C extends GuiCellModel> TableColumnModel getTableColumnModel(List<ColumnModel<T, C>> columns) {
173 TableColumnModel tableModel = new DefaultTableColumnModel();
174
175 for (int i = 0; i < columns.size(); i++) {
176 TableColumn col = new TableColumn(i);
177 ColumnModel<T, C> model = columns.get(i);
178 // if a preferred width is specified in the column definition,
179 // set the underlying TableColumn preferred width.
180 if (model.getWidth() != null && model.getWidth() >= 0) {
181 col.setPreferredWidth(model.getWidth());
182 }
183
184 // set the title
185 col.setHeaderValue(model.getHeaderTitle());
186
187 // use the cell model renderer in this instance
188 col.setCellRenderer(DEFAULT_CELL_RENDERER);
189
190 tableModel.addColumn(col);
191 }
192
193 return tableModel;
194 }
195
204 public static <T, C extends GuiCellModel> ListTableModel<T> getTableModel(List<ColumnModel<T, C>> columns) {
205 List<Function<T, ? extends Object>> columnRenderers = columns.stream()
206 .map((colModel) -> colModel.getCellRenderer())
207 .collect(Collectors.toList());
208
209 return new DefaultListTableModel<>(columnRenderers);
210 }
211
220 public static <T, C extends GuiCellModel> JTablePanel<T> getJTablePanel(List<ColumnModel<T, C>> columns) {
222 JTablePanel<T> resultTable = new JTablePanel<>(tableModel)
223 .setColumnModel(getTableColumnModel(columns))
225
226 return resultTable;
227 }
228
229 private JScrollPane tableScrollPane;
232 private JTable table;
234 private Function<T, ? extends Object> keyFunction = (rowItem) -> rowItem;
235
242 this();
244 table.setRowHeight(table.getRowHeight() + EXTRA_ROW_HEIGHT);
245 }
246
250 public JTablePanel() {
252 this.table.addMouseListener(new MouseAdapter() {
253
254 @Override
255 public void mouseClicked(MouseEvent e) {
256 // make sure click event isn't primary button and table is present
257 if (cellListener != null) {
258 int row = table.rowAtPoint(e.getPoint());
259 int col = table.columnAtPoint(e.getPoint());
260
261 // make sure there is a value at the row,col of click event.
262 if (tableModel != null
263 && row >= 0 && row < tableModel.getRowCount()
264 && col >= 0 && col < tableModel.getColumnCount()) {
265
266 Object cellValue = tableModel.getValueAt(row, col);
267 cellListener.mouseClicked(new CellMouseEvent(e, table, row, col, cellValue));
268 }
269 }
270 }
271 });
272 table.setGridColor(javax.swing.UIManager.getDefaults().getColor("InternalFrame.borderColor"));
273 }
274
284 if (tableModel == null) {
285 throw new IllegalArgumentException("Null table model passed to setModel");
286 }
287
288 this.tableModel = tableModel;
289 table.setModel(tableModel);
290 return this;
291 }
292
298 return cellListener;
299 }
300
310 this.cellListener = cellListener;
311 return this;
312 }
313
317 public TableColumnModel getColumnModel() {
318 return this.table.getColumnModel();
319 }
320
328 public JTablePanel<T> setColumnModel(TableColumnModel columnModel) {
329 this.table.setColumnModel(columnModel);
330 return this;
331 }
332
338 public Function<T, ? extends Object> getKeyFunction() {
339 return keyFunction;
340 }
341
350 public JTablePanel<T> setKeyFunction(Function<T, ? extends Object> keyFunction) {
351 if (keyFunction == null) {
352 throw new IllegalArgumentException("Key function must be non-null");
353 }
354
355 this.keyFunction = keyFunction;
356 return this;
357 }
358
364 public List<T> getSelectedItems() {
365 int selectedRow = this.table.getSelectedRow();
366 int count = this.table.getSelectedRowCount();
367 if (selectedRow < 0 || this.tableModel == null || selectedRow + count > this.tableModel.getDataRows().size()) {
368 return null;
369 } else {
370 return this.tableModel.getDataRows().subList(selectedRow, selectedRow + count);
371 }
372 }
373
374 @Override
375 protected synchronized void setResults(List<T> data) {
376 // get previously selected value
377 int prevSelectedRow = this.table.getSelectedRow();
378 List<T> tableRows = this.tableModel.getDataRows();
379 T prevValue = (tableRows != null && prevSelectedRow >= 0 && prevSelectedRow < tableRows.size())
380 ? this.tableModel.getDataRows().get(prevSelectedRow)
381 : null;
382
383 Object prevKeyValue = (prevValue == null) ? null : this.keyFunction.apply(prevValue);
384
385 // set the list of data to be shown as either the data or an empty list
386 // on null.
387 List<T> dataToSet = (data == null) ? Collections.emptyList() : data;
388
389 // set the underlying table model's data.
390 this.tableModel.setDataRows(dataToSet);
391
392 // set the row to selected value if the value is found
393 if (prevKeyValue != null) {
394 for (int objIndex = 0; objIndex < dataToSet.size(); objIndex++) {
395 Object thisKey = this.keyFunction.apply(dataToSet.get(objIndex));
396 if (prevKeyValue.equals(thisKey)) {
397 this.table.setRowSelectionInterval(objIndex, objIndex);
398 break;
399 }
400 }
401 }
402
403 }
404
405 @Override
406 protected void setMessage(boolean visible, String message) {
407 this.overlayLayer.setVisible(visible);
408 this.overlayLayer.setMessage(message);
409 }
410
414 private void initComponents() {
415 table = new JTable();
416 table.getTableHeader().setReorderingAllowed(false);
417 overlayLayer = new Overlay();
418 tableScrollPane = new JScrollPane(table);
419 JLayer<JComponent> dualLayer = new JLayer<>(tableScrollPane, overlayLayer);
420 setLayout(new BorderLayout());
421 add(dualLayer, BorderLayout.CENTER);
422 }
423}
CellMouseEvent(MouseEvent e, JTable table, int row, int col, Object cellValue)
JTablePanel< T > setColumnModel(TableColumnModel columnModel)
static< T, C extends GuiCellModel > JTablePanel< T > getJTablePanel(List< ColumnModel< T, C > > columns)
JTablePanel< T > setCellListener(CellMouseListener cellListener)
JTablePanel< T > setKeyFunction(Function< T, ? extends Object > keyFunction)
static< T, C extends GuiCellModel > ListTableModel< T > getTableModel(List< ColumnModel< T, C > > columns)
static< T, C extends GuiCellModel > TableColumnModel getTableColumnModel(List< ColumnModel< T, C > > columns)
final JTablePanel< T > setModel(ListTableModel< T > tableModel)
static final CellModelTableCellRenderer DEFAULT_CELL_RENDERER

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.