Autopsy  4.16.0
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 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  */
19 package org.sleuthkit.autopsy.datasourcesummary.uiutils;
20 
21 import java.awt.BorderLayout;
22 import java.awt.Graphics;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.function.Function;
26 import java.util.stream.Collectors;
27 import javax.swing.JComponent;
28 import javax.swing.JLayer;
29 import javax.swing.JScrollPane;
30 import javax.swing.JTable;
31 import javax.swing.plaf.LayerUI;
32 import javax.swing.table.DefaultTableColumnModel;
33 import javax.swing.table.TableColumn;
34 import javax.swing.table.TableColumnModel;
36 
41 public class JTablePanel<T> extends AbstractLoadableComponent<List<T>> {
42 
49  private static class Overlay extends LayerUI<JComponent> {
50 
51  private static final long serialVersionUID = 1L;
53 
60  void setVisible(boolean visible) {
61  overlayDelegate.setVisible(visible);
62  }
63 
69  void setMessage(String message) {
70  overlayDelegate.setMessage(message);
71  }
72 
73  @Override
74  public void paint(Graphics g, JComponent c) {
75  super.paint(g, c);
76  overlayDelegate.paintOverlay(g, c.getWidth(), c.getHeight());
77  }
78  }
79 
85  public static class ColumnModel<T> {
86 
87  private final String headerTitle;
89  private final Integer width;
90 
98  public ColumnModel(String headerTitle, Function<T, CellModelTableCellRenderer.CellModel> cellRenderer) {
99  this(headerTitle, cellRenderer, null);
100  }
101 
110  public ColumnModel(String headerTitle, Function<T, CellModelTableCellRenderer.CellModel> cellRenderer, Integer width) {
111  this.headerTitle = headerTitle;
112  this.cellRenderer = cellRenderer;
113  this.width = width;
114  }
115 
119  public String getHeaderTitle() {
120  return headerTitle;
121  }
122 
127  public Function<T, CellModel> getCellRenderer() {
128  return cellRenderer;
129  }
130 
134  public Integer getWidth() {
135  return width;
136  }
137  }
138 
139  private static final long serialVersionUID = 1L;
140 
142 
150  public static <T> TableColumnModel getTableColumnModel(List<ColumnModel<T>> columns) {
151  TableColumnModel tableModel = new DefaultTableColumnModel();
152 
153  for (int i = 0; i < columns.size(); i++) {
154  TableColumn col = new TableColumn(i);
155  ColumnModel<T> model = columns.get(i);
156  // if a preferred width is specified in the column definition,
157  // set the underlying TableColumn preferred width.
158  if (model.getWidth() != null && model.getWidth() >= 0) {
159  col.setPreferredWidth(model.getWidth());
160  }
161 
162  // set the title
163  col.setHeaderValue(model.getHeaderTitle());
164 
165  // use the cell model renderer in this instance
166  col.setCellRenderer(DEFAULT_CELL_RENDERER);
167 
168  tableModel.addColumn(col);
169  }
170 
171  return tableModel;
172  }
173 
182  public static <T> ListTableModel<T> getTableModel(List<ColumnModel<T>> columns) {
183  List<Function<T, ? extends Object>> columnRenderers = columns.stream()
184  .map((colModel) -> colModel.getCellRenderer())
185  .collect(Collectors.toList());
186 
187  return new DefaultListTableModel<T>(columnRenderers);
188  }
189 
198  public static <T> JTablePanel<T> getJTablePanel(List<ColumnModel<T>> columns) {
200  JTablePanel<T> resultTable = new JTablePanel<>(tableModel);
201  return resultTable.setColumnModel(getTableColumnModel(columns));
202  }
203 
204  private JScrollPane tableScrollPane;
205  private Overlay overlayLayer;
207  private JTable table;
208  private Function<T, ? extends Object> keyFunction = (rowItem) -> rowItem;
209 
215  public JTablePanel(ListTableModel<T> tableModel) {
216  this();
217  setModel(tableModel);
218  }
219 
223  public JTablePanel() {
224  initComponents();
225  }
226 
235  public final JTablePanel<T> setModel(ListTableModel<T> tableModel) {
236  if (tableModel == null) {
237  throw new IllegalArgumentException("Null table model passed to setModel");
238  }
239 
240  this.tableModel = tableModel;
241  table.setModel(tableModel);
242  return this;
243  }
244 
248  public TableColumnModel getColumnModel() {
249  return this.table.getColumnModel();
250  }
251 
259  public JTablePanel<T> setColumnModel(TableColumnModel columnModel) {
260  this.table.setColumnModel(columnModel);
261  return this;
262  }
263 
269  public Function<T, ? extends Object> getKeyFunction() {
270  return keyFunction;
271  }
272 
281  public JTablePanel<T> setKeyFunction(Function<T, ? extends Object> keyFunction) {
282  if (keyFunction == null) {
283  throw new IllegalArgumentException("Key function must be non-null");
284  }
285 
286  this.keyFunction = keyFunction;
287  return this;
288  }
289 
290  @Override
291  protected synchronized void setResults(List<T> data) {
292  // get previously selected value
293  int prevSelectedRow = this.table.getSelectedRow();
294  List<T> tableRows = this.tableModel.getDataRows();
295  T prevValue = (tableRows != null && prevSelectedRow >= 0 && prevSelectedRow < tableRows.size())
296  ? this.tableModel.getDataRows().get(prevSelectedRow)
297  : null;
298 
299  Object prevKeyValue = (prevValue == null) ? null : this.keyFunction.apply(prevValue);
300 
301  // set the list of data to be shown as either the data or an empty list
302  // on null.
303  List<T> dataToSet = (data == null) ? Collections.emptyList() : data;
304 
305  // set the underlying table model's data.
306  this.tableModel.setDataRows(dataToSet);
307 
308  // set the row to selected value if the value is found
309  if (prevKeyValue != null) {
310  for (int objIndex = 0; objIndex < dataToSet.size(); objIndex++) {
311  Object thisKey = this.keyFunction.apply(dataToSet.get(objIndex));
312  if (prevKeyValue.equals(thisKey)) {
313  this.table.setRowSelectionInterval(objIndex, objIndex);
314  break;
315  }
316  }
317  }
318 
319  }
320 
321  @Override
322  protected void setMessage(boolean visible, String message) {
323  this.overlayLayer.setVisible(visible);
324  this.overlayLayer.setMessage(message);
325  }
326 
330  private void initComponents() {
331  table = new JTable();
332  table.getTableHeader().setReorderingAllowed(false);
333 
334  overlayLayer = new Overlay();
335  tableScrollPane = new JScrollPane(table);
336  JLayer<JComponent> dualLayer = new JLayer<>(tableScrollPane, overlayLayer);
337  setLayout(new BorderLayout());
338  add(dualLayer, BorderLayout.CENTER);
339  }
340 }
JTablePanel< T > setColumnModel(TableColumnModel columnModel)
void setMessage(boolean visible, String message)
ColumnModel(String headerTitle, Function< T, CellModelTableCellRenderer.CellModel > cellRenderer)
ColumnModel(String headerTitle, Function< T, CellModelTableCellRenderer.CellModel > cellRenderer, Integer width)
static< T > JTablePanel< T > getJTablePanel(List< ColumnModel< T >> columns)
static< T > TableColumnModel getTableColumnModel(List< ColumnModel< T >> columns)
static< T > ListTableModel< T > getTableModel(List< ColumnModel< T >> columns)
final Function< T, CellModelTableCellRenderer.CellModel > cellRenderer
final JTablePanel< T > setModel(ListTableModel< T > tableModel)
static final CellModelTableCellRenderer DEFAULT_CELL_RENDERER
JTablePanel< T > setKeyFunction(Function< T,?extends Object > keyFunction)

Copyright © 2012-2020 Basis Technology. Generated on: Tue Sep 22 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.