19 package org.sleuthkit.autopsy.corecomponents;
21 import com.google.common.eventbus.Subscribe;
22 import java.awt.Component;
23 import java.awt.Cursor;
24 import java.awt.dnd.DnDConstants;
25 import java.awt.event.MouseAdapter;
26 import java.awt.event.MouseEvent;
27 import java.beans.FeatureDescriptor;
28 import java.beans.PropertyChangeEvent;
29 import java.beans.PropertyVetoException;
30 import java.lang.reflect.InvocationTargetException;
31 import java.util.ArrayList;
32 import java.util.Comparator;
33 import java.util.HashMap;
34 import java.util.LinkedList;
35 import java.util.List;
37 import java.util.Queue;
38 import java.util.TreeMap;
39 import java.util.TreeSet;
40 import java.util.concurrent.ConcurrentHashMap;
41 import java.util.logging.Level;
42 import java.util.prefs.PreferenceChangeEvent;
43 import java.util.prefs.Preferences;
44 import javax.swing.ImageIcon;
45 import javax.swing.JOptionPane;
46 import javax.swing.JTable;
47 import javax.swing.ListSelectionModel;
48 import static javax.swing.SwingConstants.CENTER;
49 import javax.swing.SwingUtilities;
50 import javax.swing.UIManager;
51 import javax.swing.event.ChangeEvent;
52 import javax.swing.event.ListSelectionEvent;
53 import javax.swing.event.TableColumnModelEvent;
54 import javax.swing.event.TableColumnModelListener;
55 import javax.swing.event.TreeExpansionListener;
56 import javax.swing.table.TableCellRenderer;
57 import javax.swing.table.TableColumn;
58 import javax.swing.table.TableColumnModel;
59 import org.netbeans.swing.etable.ETableColumn;
60 import org.netbeans.swing.etable.ETableColumnModel;
61 import org.netbeans.swing.outline.DefaultOutlineCellRenderer;
62 import org.netbeans.swing.outline.DefaultOutlineModel;
63 import org.netbeans.swing.outline.Outline;
64 import org.openide.explorer.ExplorerManager;
65 import org.openide.explorer.view.OutlineView;
66 import org.openide.nodes.AbstractNode;
67 import org.openide.nodes.Children;
68 import org.openide.nodes.Node;
69 import org.openide.nodes.Node.Property;
70 import org.openide.nodes.NodeEvent;
71 import org.openide.nodes.NodeListener;
72 import org.openide.nodes.NodeMemberEvent;
73 import org.openide.nodes.NodeReorderEvent;
74 import org.openide.util.ImageUtilities;
75 import org.openide.util.NbBundle;
76 import org.openide.util.NbPreferences;
77 import org.openide.util.lookup.ServiceProvider;
101 @ServiceProvider(service = DataResultViewer.class)
102 @SuppressWarnings(
"PMD.SingularField")
105 private static final long serialVersionUID = 1L;
109 private static final int SAMPLE_ROW_NUM = 100;
112 private static final int COLUMN_PADDING = 15;
115 private static final int MIN_COLUMN_WIDTH = 30;
118 private static final int MAX_COLUMN_WIDTH = 300;
121 private static final int MIN_ROW_HEIGHT = 10;
124 private static final int SCROLL_BAR_WIDTH = ((Integer) UIManager.get(
"ScrollBar.width")).intValue();
127 private static final int FIRST_COL_ADDITIONAL_WIDTH = 0;
129 private static final String NOTEPAD_ICON_PATH =
"org/sleuthkit/autopsy/images/notepad16.png";
130 private static final String RED_CIRCLE_ICON_PATH =
"org/sleuthkit/autopsy/images/red-circle-exclamation.png";
131 private static final String YELLOW_CIRCLE_ICON_PATH =
"org/sleuthkit/autopsy/images/yellow-circle-yield.png";
132 private static final ImageIcon COMMENT_ICON =
new ImageIcon(ImageUtilities.loadImage(NOTEPAD_ICON_PATH,
false));
133 private static final ImageIcon INTERESTING_SCORE_ICON =
new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH,
false));
134 private static final ImageIcon NOTABLE_ICON_SCORE =
new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH,
false));
135 @NbBundle.Messages(
"DataResultViewerTable.firstColLbl=Name")
136 static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl();
150 private final Map<String, PagingSupport> nodeNameToPagingSupportMap =
new ConcurrentHashMap<>();
165 this(null, Bundle.DataResultViewerTable_title());
178 this(explorerManager, Bundle.DataResultViewerTable_title());
192 super(explorerManager);
194 this.columnMap =
new HashMap<>();
195 this.propertiesMap =
new TreeMap<>();
202 initializePagingSupport();
208 exportCSVButton.setEnabled(
false);
214 outlineView.setAllowedDragActions(DnDConstants.ACTION_NONE);
216 outline = outlineView.getOutline();
217 outline.setRowSelectionAllowed(
true);
218 outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
219 outline.setRootVisible(
false);
220 outline.setDragEnabled(
false);
227 outline.getColumnModel().addColumnModelListener(outlineViewListener);
230 outline.getColumnModel().addColumnModelListener(iconRendererListener);
236 outline.getTableHeader().addMouseListener(outlineViewListener);
240 if (pagingSupport == null) {
253 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
258 nodeNameToPagingSupportMap.values().forEach((ps) -> {
259 ps.postPageSizeChangeEvent();
287 @NbBundle.Messages(
"DataResultViewerTable.title=Table")
312 public
void setNode(Node rootNode) {
313 if (!SwingUtilities.isEventDispatchThread()) {
314 LOGGER.log(Level.SEVERE,
"Attempting to run setNode() from non-EDT thread");
325 outline.unsetQuickFilter();
327 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
329 if (rootNode != null) {
330 this.rootNode = rootNode;
336 if (!Node.EMPTY.equals(rootNode)) {
337 String nodeName = rootNode.getName();
338 pagingSupport = nodeNameToPagingSupportMap.get(nodeName);
339 if (pagingSupport == null) {
341 nodeNameToPagingSupportMap.put(nodeName, pagingSupport);
345 rootNode.addNodeListener(
new NodeListener() {
347 public void childrenAdded(NodeMemberEvent nme) {
354 SwingUtilities.invokeLater(() -> {
360 public void childrenRemoved(NodeMemberEvent nme) {
361 SwingUtilities.invokeLater(() -> {
367 public void childrenReordered(NodeReorderEvent nre) {
372 public void nodeDestroyed(NodeEvent ne) {
377 public void propertyChange(PropertyChangeEvent evt) {
389 if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) {
390 this.getExplorerManager().setRootContext(this.rootNode);
391 outline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
394 Node emptyNode =
new AbstractNode(Children.LEAF);
395 this.getExplorerManager().setRootContext(emptyNode);
396 outline.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
398 outlineView.setPropertyColumns();
401 this.setCursor(null);
412 outlineView.addTreeExpansionListener(listener);
437 List<Node.Property<?>> props = loadColumnOrder();
438 boolean propsExist = props.isEmpty() ==
false;
439 Node.Property<?> firstProp = null;
441 firstProp = props.remove(0);
444 assignColumns(props);
445 if (firstProp != null) {
446 ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(firstProp.getDisplayName());
468 loadColumnVisibility();
488 NodeSelectionInfo selectedChildInfo = ((TableFilterNode) rootNode).getChildNodeSelectionInfo();
489 if (null != selectedChildInfo) {
490 Node[] childNodes = rootNode.getChildren().getNodes(
true);
491 for (
int i = 0; i < childNodes.length; ++i) {
492 Node childNode = childNodes[i];
493 if (selectedChildInfo.
matches(childNode)) {
494 SwingUtilities.invokeLater(() -> {
496 this.getExplorerManager().setExploredContextAndSelection(this.rootNode,
new Node[]{childNode});
497 }
catch (PropertyVetoException ex) {
498 LOGGER.log(Level.SEVERE,
"Failed to select node specified by selected child info", ex);
505 ((TableFilterNode) rootNode).setChildNodeSelectionInfo(null);
524 TableColumnModel columnModel = outline.getColumnModel();
525 int columnCount = columnModel.getColumnCount();
527 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
528 final String propName = entry.getValue().getName();
529 if (entry.getKey() < columnCount) {
530 final ETableColumn column = (ETableColumn) columnModel.getColumn(entry.getKey());
531 columnMap.put(propName, column);
543 final TableColumnModel columnModel = outline.getColumnModel();
546 double availableTableWidth = outlineView.getSize().getWidth();
548 for (
int columnIdx = 0; columnIdx < outline.getColumnCount(); columnIdx++) {
549 int columnPadding = (columnIdx == 0) ? FIRST_COL_ADDITIONAL_WIDTH + COLUMN_PADDING : COLUMN_PADDING;
550 TableColumn tableColumn = columnModel.getColumn(columnIdx);
553 int width = MIN_COLUMN_WIDTH;
557 TableCellRenderer headerRenderer = tableColumn.getHeaderRenderer();
558 if (headerRenderer == null) {
559 headerRenderer = outline.getTableHeader().getDefaultRenderer();
561 Object headerValue = tableColumn.getHeaderValue();
562 Component headerComp = headerRenderer.getTableCellRendererComponent(outline, headerValue,
false,
false, 0, columnIdx);
563 width = Math.max(headerComp.getPreferredSize().width + columnPadding, width);
566 Component comp = null;
567 int rowCount = outline.getRowCount();
568 for (
int row = 0; row < Math.min(rowCount, SAMPLE_ROW_NUM); row++) {
569 TableCellRenderer renderer = outline.getCellRenderer(row, columnIdx);
570 comp = outline.prepareRenderer(renderer, row, columnIdx);
571 width = Math.max(comp.getPreferredSize().width + columnPadding, width);
575 if (width > MAX_COLUMN_WIDTH) {
576 width = MAX_COLUMN_WIDTH;
580 if (columnIdx == outline.getColumnCount() - 1) {
581 int rowHeight = comp == null ? MIN_ROW_HEIGHT : comp.getPreferredSize().height;
582 if (headerComp.getPreferredSize().height + rowCount * rowHeight > outlineView.getSize().getHeight()) {
583 availableTableWidth -= SCROLL_BAR_WIDTH;
586 columnModel.getColumn(columnIdx).setPreferredWidth(Math.max(width, (
int) availableTableWidth));
589 columnModel.getColumn(columnIdx).setPreferredWidth(width);
590 availableTableWidth -= width;
596 return outline.getColumnModel();
604 String[] propStrings =
new String[props.size() * 2];
605 for (
int i = 0; i < props.size(); i++) {
606 final Property<?> prop = props.get(i);
607 prop.setValue(
"ComparableColumnTTV", Boolean.TRUE);
610 prop.setValue(
"TreeColumnTTV", Boolean.TRUE);
611 prop.setValue(
"SortingColumnTTV", Boolean.TRUE);
613 propStrings[2 * i] = prop.getName();
614 propStrings[2 * i + 1] = prop.getDisplayName();
616 outlineView.setPropertyColumns(propStrings);
624 if (rootNode == null || propertiesMap.isEmpty()) {
628 TableFilterNode tfn = (TableFilterNode) rootNode;
630 final ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
631 for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
632 String columnName = entry.getKey();
633 final String columnHiddenKey = ResultViewerPersistence.getColumnHiddenKey(tfn, columnName);
634 final TableColumn column = entry.getValue();
635 boolean columnHidden = columnModel.isColumnHidden(column);
637 preferences.putBoolean(columnHiddenKey,
true);
639 preferences.remove(columnHiddenKey);
650 if (rootNode == null || propertiesMap.isEmpty()) {
654 TableFilterNode tfn = (TableFilterNode) rootNode;
657 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
658 preferences.putInt(ResultViewerPersistence.getColumnPositionKey(tfn, entry.getValue().getName()), entry.getKey());
667 if (rootNode == null || propertiesMap.isEmpty()) {
671 final TableFilterNode tfn = ((TableFilterNode) rootNode);
673 ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
674 for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
675 ETableColumn etc = entry.getValue();
676 String columnName = entry.getKey();
678 final String columnSortOrderKey = ResultViewerPersistence.getColumnSortOrderKey(tfn, columnName);
679 final String columnSortRankKey = ResultViewerPersistence.getColumnSortRankKey(tfn, columnName);
680 if (etc.isSorted() && (columnModel.isColumnHidden(etc) ==
false)) {
681 preferences.putBoolean(columnSortOrderKey, etc.isAscending());
682 preferences.putInt(columnSortRankKey, etc.getSortRank());
684 columnModel.setColumnSorted(etc,
true, 0);
685 preferences.remove(columnSortOrderKey);
686 preferences.remove(columnSortRankKey);
699 if (rootNode == null || propertiesMap.isEmpty()) {
703 final TableFilterNode tfn = (TableFilterNode) rootNode;
706 TreeSet<ColumnSortInfo> sortInfos =
new TreeSet<>(Comparator.comparing(ColumnSortInfo::getRank));
707 propertiesMap.entrySet().stream().forEach(entry -> {
708 final String propName = entry.getValue().getName();
710 Integer sortRank = preferences.getInt(ResultViewerPersistence.getColumnSortRankKey(tfn, propName), 0);
712 Boolean sortOrder = preferences.getBoolean(ResultViewerPersistence.getColumnSortOrderKey(tfn, propName),
true);
713 sortInfos.add(
new ColumnSortInfo(entry.getKey(), sortRank, sortOrder));
716 sortInfos.forEach(sortInfo -> outline.setColumnSorted(sortInfo.modelIndex, sortInfo.order, sortInfo.rank));
725 if (rootNode == null || propertiesMap.isEmpty()) {
730 final TableFilterNode tfn = ((TableFilterNode) rootNode);
731 ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
732 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
733 final String propName = entry.getValue().getName();
734 boolean hidden = preferences.getBoolean(ResultViewerPersistence.getColumnHiddenKey(tfn, propName),
false);
735 final TableColumn column = columnMap.get(propName);
736 columnModel.setColumnHidden(column, hidden);
751 List<Property<?>> props = ResultViewerPersistence.getAllChildProperties(rootNode, 100);
758 final TableFilterNode tfn = ((TableFilterNode) rootNode);
759 propertiesMap.clear();
767 int offset = props.size();
771 for (Property<?> prop : props) {
772 Integer value = preferences.getInt(ResultViewerPersistence.getColumnPositionKey(tfn, prop.getName()), -1);
773 if (value >= 0 && value < offset && !propertiesMap.containsKey(value)) {
774 propertiesMap.put(value, prop);
776 propertiesMap.put(offset, prop);
787 compactPropertiesMap();
789 return new ArrayList<>(propertiesMap.values());
799 int size = propertiesMap.size();
800 Queue<Integer> availablePositions =
new LinkedList<>();
801 for (
int i = 0; i < size; i++) {
802 if (!propertiesMap.containsKey(i)) {
803 availablePositions.add(i);
808 if (availablePositions.isEmpty()) {
815 ArrayList<Integer> keys =
new ArrayList<>(propertiesMap.keySet());
816 for (
int key : keys) {
818 propertiesMap.put(availablePositions.remove(), propertiesMap.remove(key));
829 this.outlineView.removeAll();
830 this.outlineView = null;
831 super.clearComponent();
844 this.modelIndex = modelIndex;
868 this.nodeName = nodeName;
873 if (!nodeName.isEmpty()) {
881 postPageChangeEvent();
884 void previousPage() {
886 postPageChangeEvent();
889 @NbBundle.Messages({
"# {0} - totalPages",
890 "DataResultViewerTable.goToPageTextField.msgDlg=Please enter a valid page number between 1 and {0}",
891 "DataResultViewerTable.goToPageTextField.err=Invalid page number"})
893 int originalPage = currentPage;
896 currentPage = Integer.decode(gotoPageTextField.getText());
897 }
catch (NumberFormatException e) {
902 if (currentPage > totalPages || currentPage < 1) {
903 currentPage = originalPage;
904 JOptionPane.showMessageDialog(DataResultViewerTable.this,
905 Bundle.DataResultViewerTable_goToPageTextField_msgDlg(totalPages),
906 Bundle.DataResultViewerTable_goToPageTextField_err(),
907 JOptionPane.WARNING_MESSAGE);
910 postPageChangeEvent();
917 void postPageChangeEvent() {
919 BaseChildFactory.post(nodeName,
new PageChangeEvent(currentPage));
920 }
catch (BaseChildFactory.NoSuchEventBusException ex) {
921 LOGGER.log(Level.WARNING,
"Failed to post page change event.", ex);
923 DataResultViewerTable.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
931 void postPageSizeChangeEvent() {
935 if (
this == pagingSupport) {
939 BaseChildFactory.post(nodeName,
new PageSizeChangeEvent(UserPreferences.getResultsTablePageSize()));
940 }
catch (BaseChildFactory.NoSuchEventBusException ex) {
941 LOGGER.log(Level.WARNING,
"Failed to post page size change event.", ex);
953 totalPages =
event.getPageCount();
954 if (totalPages > 1) {
956 togglePageControls(
true);
960 if (nodeName.equals(rootNode.getName())) {
972 pageLabel.setVisible(onOff);
973 pagesLabel.setVisible(onOff);
974 pagePrevButton.setVisible(onOff);
975 pageNextButton.setVisible(onOff);
976 pageNumLabel.setVisible(onOff);
977 gotoPageLabel.setVisible(onOff);
978 gotoPageTextField.setVisible(onOff);
979 gotoPageTextField.setVisible(onOff);
984 @NbBundle.Messages({
"# {0} - currentPage",
"# {1} - totalPages",
985 "DataResultViewerTable.pageNumbers.curOfTotal={0} of {1}"})
987 if (totalPages == 0) {
988 pagePrevButton.setEnabled(
false);
989 pageNextButton.setEnabled(
false);
990 pageNumLabel.setText(
"");
991 gotoPageTextField.setText(
"");
992 gotoPageTextField.setEnabled(
false);
994 pageNumLabel.setText(Bundle.DataResultViewerTable_pageNumbers_curOfTotal(Integer.toString(currentPage), Integer.toString(totalPages)));
996 pageNextButton.setEnabled(currentPage != totalPages);
997 pagePrevButton.setEnabled(currentPage != 1);
998 gotoPageTextField.setEnabled(totalPages > 1);
999 gotoPageTextField.setText(
"");
1010 @NbBundle.Messages({
"DataResultViewerTable.commentRender.name=C",
1011 "DataResultViewerTable.commentRender.toolTip=C(omments) indicates whether the item has a comment",
1012 "DataResultViewerTable.scoreRender.name=S",
1013 "DataResultViewerTable.scoreRender.toolTip=S(core) indicates whether the item is interesting or notable",
1014 "DataResultViewerTable.countRender.name=O",
1015 "DataResultViewerTable.countRender.toolTip=O(ccurrences) indicates the number of data sources containing the item in the Central Repository"})
1018 if (e.getSource() instanceof ETableColumnModel) {
1019 TableColumn column = ((TableColumnModel) e.getSource()).getColumn(e.getToIndex());
1020 if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_commentRender_name())) {
1022 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_commentRender_toolTip());
1024 }
else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_scoreRender_name())) {
1026 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_scoreRender_toolTip());
1028 }
else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_countRender_name())) {
1029 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_countRender_toolTip());
1065 private class TableListener extends MouseAdapter implements TableColumnModelListener {
1069 private int startColumnIndex = -1;
1070 private int endColumnIndex = -1;
1075 int fromIndex = e.getFromIndex();
1076 int toIndex = e.getToIndex();
1077 if (fromIndex == toIndex) {
1091 if (startColumnIndex == -1) {
1092 startColumnIndex = fromIndex;
1094 endColumnIndex = toIndex;
1097 ArrayList<Integer> indicesList =
new ArrayList<>(propertiesMap.keySet());
1098 int leftIndex = Math.min(fromIndex, toIndex);
1099 int rightIndex = Math.max(fromIndex, toIndex);
1102 List<Integer> range = indicesList.subList(leftIndex, rightIndex + 1);
1103 int rangeSize = range.size();
1105 if (fromIndex < toIndex) {
1108 Property<?> movedProp = propertiesMap.get(range.get(0));
1109 for (
int i = 0; i < rangeSize - 1; i++) {
1110 propertiesMap.put(range.get(i), propertiesMap.get(range.get(i + 1)));
1112 propertiesMap.put(range.get(rangeSize - 1), movedProp);
1116 Property<?> movedProp = propertiesMap.get(range.get(rangeSize - 1));
1117 for (
int i = rangeSize - 1; i > 0; i--) {
1118 propertiesMap.put(range.get(i), propertiesMap.get(range.get(i - 1)));
1120 propertiesMap.put(range.get(0), movedProp);
1139 if (startColumnIndex != -1 && (startColumnIndex == 0 || endColumnIndex == 0)) {
1140 outline.moveColumn(endColumnIndex, startColumnIndex);
1142 startColumnIndex = -1;
1148 storeColumnSorting();
1153 columnAddedOrRemoved();
1158 columnAddedOrRemoved();
1167 if (listenToVisibilitEvents) {
1191 this.listenToVisibilitEvents = b;
1201 private static final long serialVersionUID = 1L;
1203 @NbBundle.Messages({
"DataResultViewerTable.commentRenderer.crComment.toolTip=Comment exists in Central Repository",
1204 "DataResultViewerTable.commentRenderer.tagComment.toolTip=Comment exists on associated tag(s)",
1205 "DataResultViewerTable.commentRenderer.crAndTagComment.toolTip=Comments exist both in Central Repository and on associated tag(s)",
1206 "DataResultViewerTable.commentRenderer.noComment.toolTip=No comments found"})
1209 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1210 setBackground(component.getBackground());
1211 setHorizontalAlignment(CENTER);
1212 Object switchValue = null;
1216 switchValue = ((Node.Property) value).getValue();
1217 }
catch (IllegalAccessException | InvocationTargetException ex) {
1222 switchValue = value;
1227 switch ((HasCommentStatus) switchValue) {
1229 setIcon(COMMENT_ICON);
1230 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_crComment_toolTip());
1233 setIcon(COMMENT_ICON);
1234 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_tagComment_toolTip());
1236 case CR_AND_TAG_COMMENTS:
1237 setIcon(COMMENT_ICON);
1238 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_crAndTagComment_toolTip());
1240 case TAG_NO_COMMENT:
1244 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_noComment_toolTip());
1261 private static final long serialVersionUID = 1L;
1270 private ImageIcon
getIcon(Significance significance) {
1271 if (significance == null) {
1275 switch (significance) {
1277 return NOTABLE_ICON_SCORE;
1278 case LIKELY_NOTABLE:
1279 return INTERESTING_SCORE_ICON;
1290 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1291 setBackground(component.getBackground());
1292 setHorizontalAlignment(CENTER);
1293 Object switchValue = null;
1297 switchValue = ((Node.Property) value).getValue();
1298 setToolTipText(((FeatureDescriptor) value).getShortDescription());
1299 }
catch (IllegalAccessException | InvocationTargetException ex) {
1305 switchValue = value;
1308 if ((switchValue instanceof
org.
sleuthkit.datamodel.Score)) {
1309 setIcon(getIcon(((
org.
sleuthkit.datamodel.Score) switchValue).getSignificance()));
1324 private static final long serialVersionUID = 1L;
1328 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1329 setBackground(component.getBackground());
1330 setHorizontalAlignment(LEFT);
1331 Object countValue = null;
1335 countValue = ((Node.Property) value).getValue();
1336 setToolTipText(((FeatureDescriptor) value).getShortDescription());
1337 }
catch (IllegalAccessException | InvocationTargetException ex) {
1345 if ((countValue instanceof Long)) {
1347 if ((Long) countValue >= 0) {
1348 setText(countValue.toString());
1382 @SuppressWarnings(
"unchecked")
1384 private
void initComponents() {
1386 pageLabel =
new javax.swing.JLabel();
1387 pageNumLabel =
new javax.swing.JLabel();
1388 pagesLabel =
new javax.swing.JLabel();
1389 pagePrevButton =
new javax.swing.JButton();
1390 pageNextButton =
new javax.swing.JButton();
1392 gotoPageLabel =
new javax.swing.JLabel();
1393 gotoPageTextField =
new javax.swing.JTextField();
1394 exportCSVButton =
new javax.swing.JButton();
1396 pageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageLabel.text"));
1398 pageNumLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageNumLabel.text"));
1400 pagesLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pagesLabel.text"));
1402 pagePrevButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
1403 pagePrevButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pagePrevButton.text"));
1404 pagePrevButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
1405 pagePrevButton.setFocusable(
false);
1406 pagePrevButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
1407 pagePrevButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
1408 pagePrevButton.setPreferredSize(
new java.awt.Dimension(55, 23));
1409 pagePrevButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
1410 pagePrevButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
1411 pagePrevButton.addActionListener(
new java.awt.event.ActionListener() {
1412 public void actionPerformed(java.awt.event.ActionEvent evt) {
1413 pagePrevButtonActionPerformed(evt);
1417 pageNextButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
1418 pageNextButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageNextButton.text"));
1419 pageNextButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
1420 pageNextButton.setFocusable(
false);
1421 pageNextButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
1422 pageNextButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
1423 pageNextButton.setMaximumSize(
new java.awt.Dimension(27, 23));
1424 pageNextButton.setMinimumSize(
new java.awt.Dimension(27, 23));
1425 pageNextButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
1426 pageNextButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
1427 pageNextButton.addActionListener(
new java.awt.event.ActionListener() {
1428 public void actionPerformed(java.awt.event.ActionEvent evt) {
1429 pageNextButtonActionPerformed(evt);
1433 gotoPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.gotoPageLabel.text"));
1435 gotoPageTextField.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.gotoPageTextField.text"));
1436 gotoPageTextField.addActionListener(
new java.awt.event.ActionListener() {
1437 public void actionPerformed(java.awt.event.ActionEvent evt) {
1438 gotoPageTextFieldActionPerformed(evt);
1442 exportCSVButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.exportCSVButton.text"));
1443 exportCSVButton.addActionListener(
new java.awt.event.ActionListener() {
1444 public void actionPerformed(java.awt.event.ActionEvent evt) {
1445 exportCSVButtonActionPerformed(evt);
1449 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
1450 this.setLayout(layout);
1451 layout.setHorizontalGroup(
1452 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1453 .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 904, Short.MAX_VALUE)
1454 .addGroup(layout.createSequentialGroup()
1456 .addComponent(pageLabel)
1457 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1458 .addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
1460 .addComponent(pagesLabel)
1461 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
1462 .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
1463 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1464 .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
1465 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
1466 .addComponent(gotoPageLabel)
1467 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1468 .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
1469 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
1470 .addComponent(exportCSVButton))
1473 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {pageNextButton, pagePrevButton});
1475 layout.setVerticalGroup(
1476 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1477 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
1479 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
1480 .addComponent(pageLabel)
1481 .addComponent(pageNumLabel)
1482 .addComponent(pagesLabel)
1483 .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
1484 .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
1485 .addComponent(gotoPageLabel)
1486 .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
1487 .addComponent(exportCSVButton))
1489 .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE)
1493 layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {pageNextButton, pagePrevButton});
1495 gotoPageLabel.getAccessibleContext().setAccessibleName(
"");
1499 pagingSupport.previousPage();
1503 pagingSupport.nextPage();
1507 pagingSupport.gotoPage();
1510 @NbBundle.Messages({
"DataResultViewerTable.exportCSVButtonActionPerformed.empty=No data to export"
1513 Node currentRoot = this.getExplorerManager().getRootContext();
1514 if (currentRoot != null && currentRoot.getChildren().getNodesCount() > 0) {
javax.swing.JLabel pageLabel
void mouseReleased(MouseEvent e)
boolean matches(Node candidateNode)
javax.swing.JLabel pageNumLabel
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
TableColumnModel getColumnModel()
final Map< String, ETableColumn > columnMap
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
org.openide.explorer.view.OutlineView outlineView
void compactPropertiesMap()
ImageIcon getIcon(Significance significance)
void columnRemoved(TableColumnModelEvent e)
void columnAdded(TableColumnModelEvent e)
synchronized List< Node.Property<?> > loadColumnOrder()
synchronized void storeColumnVisibility()
void pageNextButtonActionPerformed(java.awt.event.ActionEvent evt)
void subscribeToPageCountChange(PageCountChangeEvent event)
static void register(String nodeName, Object subscriber)
synchronized void storeColumnSorting()
javax.swing.JButton pageNextButton
synchronized void assignColumns(List< Property<?>> props)
final IconRendererTableListener iconRendererListener
void columnMarginChanged(ChangeEvent e)
static final String FIRST_COLUMN_LABEL
void mouseClicked(MouseEvent e)
void columnSelectionChanged(ListSelectionEvent e)
void columnRemoved(TableColumnModelEvent e)
javax.swing.JTextField gotoPageTextField
final TableListener outlineViewListener
void columnAddedOrRemoved()
void exportCSVButtonActionPerformed(java.awt.event.ActionEvent evt)
boolean listenToVisibilitEvents
void columnMoved(TableColumnModelEvent e)
DataResultViewer createInstance()
javax.swing.JLabel gotoPageLabel
static final String RESULTS_TABLE_PAGE_SIZE
final Map< Integer, Property<?> > propertiesMap
void gotoPageTextFieldActionPerformed(java.awt.event.ActionEvent evt)
void columnSelectionChanged(ListSelectionEvent e)
javax.swing.JButton pagePrevButton
javax.swing.JLabel pagesLabel
synchronized void loadColumnVisibility()
ColumnSortInfo(int modelIndex, int rank, boolean order)
void addTreeExpansionListener(TreeExpansionListener listener)
void listenToVisibilityChanges(boolean b)
synchronized static Logger getLogger(String name)
synchronized void loadColumnSorting()
static void addChangeListener(PreferenceChangeListener listener)
void pagePrevButtonActionPerformed(java.awt.event.ActionEvent evt)
void initializePagingSupport()
static void info(String message)
void columnMoved(TableColumnModelEvent e)
javax.swing.JButton exportCSVButton
DataResultViewerTable(ExplorerManager explorerManager)
void columnMarginChanged(ChangeEvent e)
boolean isSupported(Node candidateRootNode)
static void saveNodesToCSV(Collection<?extends Node > nodesToExport, Component component)
void columnAdded(TableColumnModelEvent e)
synchronized void storeColumnOrder()
DataResultViewerTable(ExplorerManager explorerManager, String title)
void togglePageControls(boolean onOff)