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.FontMetrics;
25 import java.awt.Graphics;
26 import java.awt.dnd.DnDConstants;
27 import java.awt.event.MouseAdapter;
28 import java.awt.event.MouseEvent;
29 import java.beans.FeatureDescriptor;
30 import java.beans.PropertyChangeEvent;
31 import java.beans.PropertyVetoException;
32 import java.lang.reflect.InvocationTargetException;
33 import java.util.ArrayList;
34 import java.util.Comparator;
35 import java.util.HashMap;
36 import java.util.LinkedList;
37 import java.util.List;
39 import java.util.Queue;
40 import java.util.TreeMap;
41 import java.util.TreeSet;
42 import java.util.concurrent.ConcurrentHashMap;
43 import java.util.logging.Level;
44 import java.util.prefs.PreferenceChangeEvent;
45 import java.util.prefs.Preferences;
46 import javax.swing.ImageIcon;
47 import javax.swing.JOptionPane;
48 import javax.swing.JTable;
49 import javax.swing.ListSelectionModel;
50 import static javax.swing.SwingConstants.CENTER;
51 import javax.swing.SwingUtilities;
52 import javax.swing.event.ChangeEvent;
53 import javax.swing.event.ListSelectionEvent;
54 import javax.swing.event.TableColumnModelEvent;
55 import javax.swing.event.TableColumnModelListener;
56 import javax.swing.event.TreeExpansionListener;
57 import javax.swing.table.TableCellRenderer;
58 import javax.swing.table.TableColumn;
59 import javax.swing.table.TableColumnModel;
60 import org.netbeans.swing.etable.ETableColumn;
61 import org.netbeans.swing.etable.ETableColumnModel;
62 import org.netbeans.swing.outline.DefaultOutlineCellRenderer;
63 import org.netbeans.swing.outline.DefaultOutlineModel;
64 import org.netbeans.swing.outline.Outline;
65 import org.openide.explorer.ExplorerManager;
66 import org.openide.explorer.view.OutlineView;
67 import org.openide.nodes.AbstractNode;
68 import org.openide.nodes.Children;
69 import org.openide.nodes.Node;
70 import org.openide.nodes.Node.Property;
71 import org.openide.nodes.NodeEvent;
72 import org.openide.nodes.NodeListener;
73 import org.openide.nodes.NodeMemberEvent;
74 import org.openide.nodes.NodeReorderEvent;
75 import org.openide.util.ImageUtilities;
76 import org.openide.util.NbBundle;
77 import org.openide.util.NbPreferences;
78 import org.openide.util.lookup.ServiceProvider;
101 @ServiceProvider(service = DataResultViewer.class)
102 @SuppressWarnings(
"PMD.SingularField")
105 private static final long serialVersionUID = 1L;
108 private static final String NOTEPAD_ICON_PATH =
"org/sleuthkit/autopsy/images/notepad16.png";
109 private static final String RED_CIRCLE_ICON_PATH =
"org/sleuthkit/autopsy/images/red-circle-exclamation.png";
110 private static final String YELLOW_CIRCLE_ICON_PATH =
"org/sleuthkit/autopsy/images/yellow-circle-yield.png";
111 private static final ImageIcon COMMENT_ICON =
new ImageIcon(ImageUtilities.loadImage(NOTEPAD_ICON_PATH,
false));
112 private static final ImageIcon INTERESTING_SCORE_ICON =
new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH,
false));
113 private static final ImageIcon NOTABLE_ICON_SCORE =
new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH,
false));
114 @NbBundle.Messages(
"DataResultViewerTable.firstColLbl=Name")
115 static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl();
129 private final Map<String, PagingSupport> nodeNameToPagingSupportMap =
new ConcurrentHashMap<>();
144 this(null, Bundle.DataResultViewerTable_title());
157 this(explorerManager, Bundle.DataResultViewerTable_title());
171 super(explorerManager);
173 this.columnMap =
new HashMap<>();
174 this.propertiesMap =
new TreeMap<>();
181 initializePagingSupport();
187 exportCSVButton.setEnabled(
false);
193 outlineView.setAllowedDragActions(DnDConstants.ACTION_NONE);
195 outline = outlineView.getOutline();
196 outline.setRowSelectionAllowed(
true);
197 outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
198 outline.setRootVisible(
false);
199 outline.setDragEnabled(
false);
206 outline.getColumnModel().addColumnModelListener(outlineViewListener);
209 outline.getColumnModel().addColumnModelListener(iconRendererListener);
215 outline.getTableHeader().addMouseListener(outlineViewListener);
219 if (pagingSupport == null) {
232 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
237 nodeNameToPagingSupportMap.values().forEach((ps) -> {
238 ps.postPageSizeChangeEvent();
264 @NbBundle.Messages(
"DataResultViewerTable.title=Table")
289 public
void setNode(Node rootNode) {
290 if (!SwingUtilities.isEventDispatchThread()) {
291 LOGGER.log(Level.SEVERE,
"Attempting to run setNode() from non-EDT thread");
302 outline.unsetQuickFilter();
304 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
306 if (rootNode != null) {
307 this.rootNode = rootNode;
313 String nodeName = rootNode.getName();
314 pagingSupport = nodeNameToPagingSupportMap.get(nodeName);
315 if (pagingSupport == null) {
317 nodeNameToPagingSupportMap.put(nodeName, pagingSupport);
321 rootNode.addNodeListener(
new NodeListener() {
323 public void childrenAdded(NodeMemberEvent nme) {
330 SwingUtilities.invokeLater(() -> {
336 public void childrenRemoved(NodeMemberEvent nme) {
337 SwingUtilities.invokeLater(() -> {
343 public void childrenReordered(NodeReorderEvent nre) {
348 public void nodeDestroyed(NodeEvent ne) {
353 public void propertyChange(PropertyChangeEvent evt) {
370 if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) {
371 this.getExplorerManager().setRootContext(this.rootNode);
374 Node emptyNode =
new AbstractNode(Children.LEAF);
375 this.getExplorerManager().setRootContext(emptyNode);
376 outline.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
378 outlineView.setPropertyColumns();
381 this.setCursor(null);
392 outlineView.addTreeExpansionListener(listener);
417 List<Node.Property<?>> props = loadColumnOrder();
418 boolean propsExist = props.isEmpty() ==
false;
419 Node.Property<?> firstProp = null;
421 firstProp = props.remove(0);
429 outline.setAutoResizeMode((props.isEmpty()) ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF);
431 assignColumns(props);
432 if (firstProp != null) {
433 ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(firstProp.getDisplayName());
457 loadColumnVisibility();
463 SwingUtilities.invokeLater(() -> {
465 NodeSelectionInfo selectedChildInfo = ((TableFilterNode) rootNode).getChildNodeSelectionInfo();
466 if (null != selectedChildInfo) {
467 Node[] childNodes = rootNode.getChildren().getNodes(
true);
468 for (
int i = 0; i < childNodes.length; ++i) {
469 Node childNode = childNodes[i];
470 if (selectedChildInfo.
matches(childNode)) {
472 this.getExplorerManager().setSelectedNodes(
new Node[]{childNode});
473 }
catch (PropertyVetoException ex) {
474 LOGGER.log(Level.SEVERE,
"Failed to select node specified by selected child info", ex);
479 ((TableFilterNode) rootNode).setChildNodeSelectionInfo(null);
499 TableColumnModel columnModel = outline.getColumnModel();
500 int columnCount = columnModel.getColumnCount();
502 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
503 final String propName = entry.getValue().getName();
504 if (entry.getKey() < columnCount) {
505 final ETableColumn column = (ETableColumn) columnModel.getColumn(entry.getKey());
506 columnMap.put(propName, column);
517 if (rootNode.getChildren().getNodesCount() != 0) {
518 final Graphics graphics = outlineView.getGraphics();
520 if (graphics != null) {
522 double outlineViewWidth = outlineView.getSize().getWidth();
524 List<Integer> columnWidths =
new ArrayList<>();
525 final FontMetrics metrics = graphics.getFontMetrics();
530 int totalColumnWidth = 0;
531 int cntMaxSizeColumns =0;
535 for (
int column = 0; column < outline.getModel().getColumnCount(); column++) {
536 int firstColumnPadding = (column == 0) ? 32 : 0;
537 int columnWidthLimit = (column == 0) ? 350 : 300;
541 for (
int row = 0; row < Math.min(100, outline.getRowCount()); row++) {
542 TableCellRenderer renderer = outline.getCellRenderer(row, column);
543 Component comp = outline.prepareRenderer(renderer, row, column);
544 valuesWidth = Math.max(comp.getPreferredSize().width, valuesWidth);
547 int headerWidth = metrics.stringWidth(outline.getColumnName(column));
548 valuesWidth += firstColumnPadding;
550 int columnWidth = Math.max(valuesWidth, headerWidth);
551 columnWidth += 2 * margin + padding;
553 columnWidth = Math.min(columnWidth, columnWidthLimit);
554 columnWidths.add(columnWidth);
556 totalColumnWidth += columnWidth;
558 if( columnWidth == columnWidthLimit) {
570 if (totalColumnWidth < outlineViewWidth) {
571 if (cntMaxSizeColumns > 0) {
572 extraWidth = (int) ((outlineViewWidth - totalColumnWidth)/cntMaxSizeColumns);
574 extraWidth = (int) ((outlineViewWidth - totalColumnWidth)/columnWidths.size());
578 for(
int column = 0; column < columnWidths.size(); column++) {
579 int columnWidth = columnWidths.get(column);
581 if(cntMaxSizeColumns > 0) {
582 if(columnWidth >= ((column == 0) ? 350 : 300)) {
583 columnWidth += extraWidth;
586 columnWidth += extraWidth;
589 outline.getColumnModel().getColumn(column).setPreferredWidth(columnWidth);
594 outline.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
599 return outline.getColumnModel();
607 String[] propStrings =
new String[props.size() * 2];
608 for (
int i = 0; i < props.size(); i++) {
609 final Property<?> prop = props.get(i);
610 prop.setValue(
"ComparableColumnTTV", Boolean.TRUE);
613 prop.setValue(
"TreeColumnTTV", Boolean.TRUE);
614 prop.setValue(
"SortingColumnTTV", Boolean.TRUE);
616 propStrings[2 * i] = prop.getName();
617 propStrings[2 * i + 1] = prop.getDisplayName();
619 outlineView.setPropertyColumns(propStrings);
627 if (rootNode == null || propertiesMap.isEmpty()) {
631 TableFilterNode tfn = (TableFilterNode) rootNode;
633 final ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
634 for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
635 String columnName = entry.getKey();
636 final String columnHiddenKey = ResultViewerPersistence.getColumnHiddenKey(tfn, columnName);
637 final TableColumn column = entry.getValue();
638 boolean columnHidden = columnModel.isColumnHidden(column);
640 preferences.putBoolean(columnHiddenKey,
true);
642 preferences.remove(columnHiddenKey);
653 if (rootNode == null || propertiesMap.isEmpty()) {
657 TableFilterNode tfn = (TableFilterNode) rootNode;
660 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
661 preferences.putInt(ResultViewerPersistence.getColumnPositionKey(tfn, entry.getValue().getName()), entry.getKey());
670 if (rootNode == null || propertiesMap.isEmpty()) {
674 final TableFilterNode tfn = ((TableFilterNode) rootNode);
676 ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
677 for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
678 ETableColumn etc = entry.getValue();
679 String columnName = entry.getKey();
681 final String columnSortOrderKey = ResultViewerPersistence.getColumnSortOrderKey(tfn, columnName);
682 final String columnSortRankKey = ResultViewerPersistence.getColumnSortRankKey(tfn, columnName);
683 if (etc.isSorted() && (columnModel.isColumnHidden(etc) ==
false)) {
684 preferences.putBoolean(columnSortOrderKey, etc.isAscending());
685 preferences.putInt(columnSortRankKey, etc.getSortRank());
687 columnModel.setColumnSorted(etc,
true, 0);
688 preferences.remove(columnSortOrderKey);
689 preferences.remove(columnSortRankKey);
702 if (rootNode == null || propertiesMap.isEmpty()) {
706 final TableFilterNode tfn = (TableFilterNode) rootNode;
709 TreeSet<ColumnSortInfo> sortInfos =
new TreeSet<>(Comparator.comparing(ColumnSortInfo::getRank));
710 propertiesMap.entrySet().stream().forEach(entry -> {
711 final String propName = entry.getValue().getName();
713 Integer sortRank = preferences.getInt(ResultViewerPersistence.getColumnSortRankKey(tfn, propName), 0);
715 Boolean sortOrder = preferences.getBoolean(ResultViewerPersistence.getColumnSortOrderKey(tfn, propName),
true);
716 sortInfos.add(
new ColumnSortInfo(entry.getKey(), sortRank, sortOrder));
719 sortInfos.forEach(sortInfo -> outline.setColumnSorted(sortInfo.modelIndex, sortInfo.order, sortInfo.rank));
728 if (rootNode == null || propertiesMap.isEmpty()) {
733 final TableFilterNode tfn = ((TableFilterNode) rootNode);
734 ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
735 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
736 final String propName = entry.getValue().getName();
737 boolean hidden = preferences.getBoolean(ResultViewerPersistence.getColumnHiddenKey(tfn, propName),
false);
738 final TableColumn column = columnMap.get(propName);
739 columnModel.setColumnHidden(column, hidden);
754 List<Property<?>> props = ResultViewerPersistence.getAllChildProperties(rootNode, 100);
761 final TableFilterNode tfn = ((TableFilterNode) rootNode);
762 propertiesMap.clear();
770 int offset = props.size();
774 for (Property<?> prop : props) {
775 Integer value = preferences.getInt(ResultViewerPersistence.getColumnPositionKey(tfn, prop.getName()), -1);
776 if (value >= 0 && value < offset && !propertiesMap.containsKey(value)) {
777 propertiesMap.put(value, prop);
779 propertiesMap.put(offset, prop);
789 compactPropertiesMap();
791 return new ArrayList<>(propertiesMap.values());
801 int size = propertiesMap.size();
802 Queue<Integer> availablePositions =
new LinkedList<>();
803 for (
int i = 0; i < size; i++) {
804 if (!propertiesMap.containsKey(i)) {
805 availablePositions.add(i);
810 if (availablePositions.isEmpty()) {
817 ArrayList<Integer> keys =
new ArrayList<>(propertiesMap.keySet());
818 for (
int key : keys) {
820 propertiesMap.put(availablePositions.remove(), propertiesMap.remove(key));
831 this.outlineView.removeAll();
832 this.outlineView = null;
833 super.clearComponent();
846 this.modelIndex = modelIndex;
870 this.nodeName = nodeName;
875 if (!nodeName.isEmpty()) {
883 postPageChangeEvent();
886 void previousPage() {
888 postPageChangeEvent();
891 @NbBundle.Messages({
"# {0} - totalPages",
892 "DataResultViewerTable.goToPageTextField.msgDlg=Please enter a valid page number between 1 and {0}",
893 "DataResultViewerTable.goToPageTextField.err=Invalid page number"})
895 int originalPage = currentPage;
898 currentPage = Integer.decode(gotoPageTextField.getText());
899 }
catch (NumberFormatException e) {
904 if (currentPage > totalPages || currentPage < 1) {
905 currentPage = originalPage;
906 JOptionPane.showMessageDialog(DataResultViewerTable.this,
907 Bundle.DataResultViewerTable_goToPageTextField_msgDlg(totalPages),
908 Bundle.DataResultViewerTable_goToPageTextField_err(),
909 JOptionPane.WARNING_MESSAGE);
912 postPageChangeEvent();
919 void postPageChangeEvent() {
921 BaseChildFactory.post(nodeName,
new PageChangeEvent(currentPage));
922 }
catch (BaseChildFactory.NoSuchEventBusException ex) {
923 LOGGER.log(Level.WARNING,
"Failed to post page change event.", ex);
925 DataResultViewerTable.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
933 void postPageSizeChangeEvent() {
937 if (
this == pagingSupport) {
941 BaseChildFactory.post(nodeName,
new PageSizeChangeEvent(UserPreferences.getResultsTablePageSize()));
942 }
catch (BaseChildFactory.NoSuchEventBusException ex) {
943 LOGGER.log(Level.WARNING,
"Failed to post page size change event.", ex);
955 totalPages =
event.getPageCount();
956 if (totalPages > 1) {
958 togglePageControls(
true);
962 if (nodeName.equals(rootNode.getName())) {
974 pageLabel.setVisible(onOff);
975 pagesLabel.setVisible(onOff);
976 pagePrevButton.setVisible(onOff);
977 pageNextButton.setVisible(onOff);
978 pageNumLabel.setVisible(onOff);
979 gotoPageLabel.setVisible(onOff);
980 gotoPageTextField.setVisible(onOff);
981 gotoPageTextField.setVisible(onOff);
986 @NbBundle.Messages({
"# {0} - currentPage",
"# {1} - totalPages",
987 "DataResultViewerTable.pageNumbers.curOfTotal={0} of {1}"})
989 if (totalPages == 0) {
990 pagePrevButton.setEnabled(
false);
991 pageNextButton.setEnabled(
false);
992 pageNumLabel.setText(
"");
993 gotoPageTextField.setText(
"");
994 gotoPageTextField.setEnabled(
false);
996 pageNumLabel.setText(Bundle.DataResultViewerTable_pageNumbers_curOfTotal(Integer.toString(currentPage), Integer.toString(totalPages)));
998 pageNextButton.setEnabled(currentPage != totalPages);
999 pagePrevButton.setEnabled(currentPage != 1);
1000 gotoPageTextField.setEnabled(totalPages > 1);
1001 gotoPageTextField.setText(
"");
1012 @NbBundle.Messages({
"DataResultViewerTable.commentRender.name=C",
1013 "DataResultViewerTable.commentRender.toolTip=C(omments) indicates whether the item has a comment",
1014 "DataResultViewerTable.scoreRender.name=S",
1015 "DataResultViewerTable.scoreRender.toolTip=S(core) indicates whether the item is interesting or notable",
1016 "DataResultViewerTable.countRender.name=O",
1017 "DataResultViewerTable.countRender.toolTip=O(ccurrences) indicates the number of data sources containing the item in the Central Repository"})
1020 if (e.getSource() instanceof ETableColumnModel) {
1021 TableColumn column = ((TableColumnModel) e.getSource()).getColumn(e.getToIndex());
1022 if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_commentRender_name())) {
1024 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_commentRender_toolTip());
1026 }
else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_scoreRender_name())) {
1028 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_scoreRender_toolTip());
1030 }
else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_countRender_name())) {
1031 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_countRender_toolTip());
1067 private class TableListener extends MouseAdapter implements TableColumnModelListener {
1071 private int startColumnIndex = -1;
1072 private int endColumnIndex = -1;
1077 int fromIndex = e.getFromIndex();
1078 int toIndex = e.getToIndex();
1079 if (fromIndex == toIndex) {
1093 if (startColumnIndex == -1) {
1094 startColumnIndex = fromIndex;
1096 endColumnIndex = toIndex;
1099 ArrayList<Integer> indicesList =
new ArrayList<>(propertiesMap.keySet());
1100 int leftIndex = Math.min(fromIndex, toIndex);
1101 int rightIndex = Math.max(fromIndex, toIndex);
1104 List<Integer> range = indicesList.subList(leftIndex, rightIndex + 1);
1105 int rangeSize = range.size();
1107 if (fromIndex < toIndex) {
1110 Property<?> movedProp = propertiesMap.get(range.get(0));
1111 for (
int i = 0; i < rangeSize - 1; i++) {
1112 propertiesMap.put(range.get(i), propertiesMap.get(range.get(i + 1)));
1114 propertiesMap.put(range.get(rangeSize - 1), movedProp);
1118 Property<?> movedProp = propertiesMap.get(range.get(rangeSize - 1));
1119 for (
int i = rangeSize - 1; i > 0; i--) {
1120 propertiesMap.put(range.get(i), propertiesMap.get(range.get(i - 1)));
1122 propertiesMap.put(range.get(0), movedProp);
1141 if (startColumnIndex != -1 && (startColumnIndex == 0 || endColumnIndex == 0)) {
1142 outline.moveColumn(endColumnIndex, startColumnIndex);
1144 startColumnIndex = -1;
1150 storeColumnSorting();
1155 columnAddedOrRemoved();
1160 columnAddedOrRemoved();
1169 if (listenToVisibilitEvents) {
1193 this.listenToVisibilitEvents = b;
1203 private static final long serialVersionUID = 1L;
1205 @NbBundle.Messages({
"DataResultViewerTable.commentRenderer.crComment.toolTip=Comment exists in Central Repository",
1206 "DataResultViewerTable.commentRenderer.tagComment.toolTip=Comment exists on associated tag(s)",
1207 "DataResultViewerTable.commentRenderer.crAndTagComment.toolTip=Comments exist both in Central Repository and on associated tag(s)",
1208 "DataResultViewerTable.commentRenderer.noComment.toolTip=No comments found"})
1211 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1212 setBackground(component.getBackground());
1213 setHorizontalAlignment(CENTER);
1214 Object switchValue = null;
1218 switchValue = ((Node.Property) value).getValue();
1219 }
catch (IllegalAccessException | InvocationTargetException ex) {
1224 switchValue = value;
1229 switch ((HasCommentStatus) switchValue) {
1231 setIcon(COMMENT_ICON);
1232 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_crComment_toolTip());
1235 setIcon(COMMENT_ICON);
1236 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_tagComment_toolTip());
1238 case CR_AND_TAG_COMMENTS:
1239 setIcon(COMMENT_ICON);
1240 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_crAndTagComment_toolTip());
1242 case TAG_NO_COMMENT:
1246 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_noComment_toolTip());
1263 private static final long serialVersionUID = 1L;
1267 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1268 setBackground(component.getBackground());
1269 setHorizontalAlignment(CENTER);
1270 Object switchValue = null;
1274 switchValue = ((Node.Property) value).getValue();
1275 setToolTipText(((FeatureDescriptor) value).getShortDescription());
1276 }
catch (IllegalAccessException | InvocationTargetException ex) {
1282 switchValue = value;
1285 if ((switchValue instanceof
Score)) {
1287 switch ((Score) switchValue) {
1288 case INTERESTING_SCORE:
1289 setIcon(INTERESTING_SCORE_ICON);
1292 setIcon(NOTABLE_ICON_SCORE);
1312 private static final long serialVersionUID = 1L;
1316 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1317 setBackground(component.getBackground());
1318 setHorizontalAlignment(LEFT);
1319 Object countValue = null;
1323 countValue = ((Node.Property) value).getValue();
1324 setToolTipText(((FeatureDescriptor) value).getShortDescription());
1325 }
catch (IllegalAccessException | InvocationTargetException ex) {
1333 if ((countValue instanceof Long)) {
1335 if ((Long) countValue >= 0) {
1336 setText(countValue.toString());
1370 @SuppressWarnings(
"unchecked")
1372 private
void initComponents() {
1374 pageLabel =
new javax.swing.JLabel();
1375 pageNumLabel =
new javax.swing.JLabel();
1376 pagesLabel =
new javax.swing.JLabel();
1377 pagePrevButton =
new javax.swing.JButton();
1378 pageNextButton =
new javax.swing.JButton();
1380 gotoPageLabel =
new javax.swing.JLabel();
1381 gotoPageTextField =
new javax.swing.JTextField();
1382 exportCSVButton =
new javax.swing.JButton();
1384 pageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageLabel.text"));
1386 pageNumLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageNumLabel.text"));
1388 pagesLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pagesLabel.text"));
1390 pagePrevButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
1391 pagePrevButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pagePrevButton.text"));
1392 pagePrevButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
1393 pagePrevButton.setFocusable(
false);
1394 pagePrevButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
1395 pagePrevButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
1396 pagePrevButton.setPreferredSize(
new java.awt.Dimension(55, 23));
1397 pagePrevButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
1398 pagePrevButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
1399 pagePrevButton.addActionListener(
new java.awt.event.ActionListener() {
1400 public void actionPerformed(java.awt.event.ActionEvent evt) {
1401 pagePrevButtonActionPerformed(evt);
1405 pageNextButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
1406 pageNextButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageNextButton.text"));
1407 pageNextButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
1408 pageNextButton.setFocusable(
false);
1409 pageNextButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
1410 pageNextButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
1411 pageNextButton.setMaximumSize(
new java.awt.Dimension(27, 23));
1412 pageNextButton.setMinimumSize(
new java.awt.Dimension(27, 23));
1413 pageNextButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
1414 pageNextButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
1415 pageNextButton.addActionListener(
new java.awt.event.ActionListener() {
1416 public void actionPerformed(java.awt.event.ActionEvent evt) {
1417 pageNextButtonActionPerformed(evt);
1421 gotoPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.gotoPageLabel.text"));
1423 gotoPageTextField.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.gotoPageTextField.text"));
1424 gotoPageTextField.addActionListener(
new java.awt.event.ActionListener() {
1425 public void actionPerformed(java.awt.event.ActionEvent evt) {
1426 gotoPageTextFieldActionPerformed(evt);
1430 exportCSVButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.exportCSVButton.text"));
1431 exportCSVButton.addActionListener(
new java.awt.event.ActionListener() {
1432 public void actionPerformed(java.awt.event.ActionEvent evt) {
1433 exportCSVButtonActionPerformed(evt);
1437 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
1438 this.setLayout(layout);
1439 layout.setHorizontalGroup(
1440 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1441 .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 904, Short.MAX_VALUE)
1442 .addGroup(layout.createSequentialGroup()
1444 .addComponent(pageLabel)
1445 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1446 .addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
1448 .addComponent(pagesLabel)
1449 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
1450 .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
1451 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1452 .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
1453 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
1454 .addComponent(gotoPageLabel)
1455 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1456 .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
1457 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
1458 .addComponent(exportCSVButton))
1461 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {pageNextButton, pagePrevButton});
1463 layout.setVerticalGroup(
1464 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1465 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
1467 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
1468 .addComponent(pageLabel)
1469 .addComponent(pageNumLabel)
1470 .addComponent(pagesLabel)
1471 .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
1472 .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
1473 .addComponent(gotoPageLabel)
1474 .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
1475 .addComponent(exportCSVButton))
1477 .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE)
1481 layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {pageNextButton, pagePrevButton});
1483 gotoPageLabel.getAccessibleContext().setAccessibleName(
"");
1487 pagingSupport.previousPage();
1491 pagingSupport.nextPage();
1495 pagingSupport.gotoPage();
1498 @NbBundle.Messages({
"DataResultViewerTable.exportCSVButtonActionPerformed.empty=No data to export"
1501 Node currentRoot = this.getExplorerManager().getRootContext();
1502 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()
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)