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.List;
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.event.ChangeEvent;
51 import javax.swing.event.ListSelectionEvent;
52 import javax.swing.event.TableColumnModelEvent;
53 import javax.swing.event.TableColumnModelListener;
54 import javax.swing.event.TreeExpansionListener;
55 import javax.swing.table.TableCellRenderer;
56 import javax.swing.table.TableColumn;
57 import javax.swing.table.TableColumnModel;
58 import org.netbeans.swing.etable.ETableColumn;
59 import org.netbeans.swing.etable.ETableColumnModel;
60 import org.netbeans.swing.outline.DefaultOutlineCellRenderer;
61 import org.netbeans.swing.outline.DefaultOutlineModel;
62 import org.netbeans.swing.outline.Outline;
63 import org.openide.explorer.ExplorerManager;
64 import org.openide.explorer.view.OutlineView;
65 import org.openide.nodes.AbstractNode;
66 import org.openide.nodes.Children;
67 import org.openide.nodes.Node;
68 import org.openide.nodes.Node.Property;
69 import org.openide.nodes.NodeEvent;
70 import org.openide.nodes.NodeListener;
71 import org.openide.nodes.NodeMemberEvent;
72 import org.openide.nodes.NodeReorderEvent;
73 import org.openide.util.ImageUtilities;
74 import org.openide.util.NbBundle;
75 import org.openide.util.NbPreferences;
76 import org.openide.util.lookup.ServiceProvider;
99 @ServiceProvider(service = DataResultViewer.class)
100 @SuppressWarnings(
"PMD.SingularField")
103 private static final long serialVersionUID = 1L;
106 private static final String NOTEPAD_ICON_PATH =
"org/sleuthkit/autopsy/images/notepad16.png";
107 private static final String RED_CIRCLE_ICON_PATH =
"org/sleuthkit/autopsy/images/red-circle-exclamation.png";
108 private static final String YELLOW_CIRCLE_ICON_PATH =
"org/sleuthkit/autopsy/images/yellow-circle-yield.png";
109 private static final ImageIcon COMMENT_ICON =
new ImageIcon(ImageUtilities.loadImage(NOTEPAD_ICON_PATH,
false));
110 private static final ImageIcon INTERESTING_SCORE_ICON =
new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH,
false));
111 private static final ImageIcon NOTABLE_ICON_SCORE =
new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH,
false));
112 @NbBundle.Messages(
"DataResultViewerTable.firstColLbl=Name")
113 static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl();
127 private final Map<String, PagingSupport> nodeNameToPagingSupportMap =
new ConcurrentHashMap<>();
142 this(null, Bundle.DataResultViewerTable_title());
155 this(explorerManager, Bundle.DataResultViewerTable_title());
169 super(explorerManager);
171 this.columnMap =
new HashMap<>();
172 this.propertiesMap =
new TreeMap<>();
179 initializePagingSupport();
185 exportCSVButton.setEnabled(
false);
191 outlineView.setAllowedDragActions(DnDConstants.ACTION_NONE);
193 outline = outlineView.getOutline();
194 outline.setRowSelectionAllowed(
true);
195 outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
196 outline.setRootVisible(
false);
197 outline.setDragEnabled(
false);
204 outline.getColumnModel().addColumnModelListener(outlineViewListener);
207 outline.getColumnModel().addColumnModelListener(iconRendererListener);
213 outline.getTableHeader().addMouseListener(outlineViewListener);
217 if (pagingSupport == null) {
230 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
235 nodeNameToPagingSupportMap.values().forEach((ps) -> {
236 ps.postPageSizeChangeEvent();
262 @NbBundle.Messages(
"DataResultViewerTable.title=Table")
287 public
void setNode(Node rootNode) {
288 if (!SwingUtilities.isEventDispatchThread()) {
289 LOGGER.log(Level.SEVERE,
"Attempting to run setNode() from non-EDT thread");
300 outline.unsetQuickFilter();
302 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
304 if (rootNode != null) {
305 this.rootNode = rootNode;
311 String nodeName = rootNode.getName();
312 pagingSupport = nodeNameToPagingSupportMap.get(nodeName);
313 if (pagingSupport == null) {
315 nodeNameToPagingSupportMap.put(nodeName, pagingSupport);
319 rootNode.addNodeListener(
new NodeListener() {
321 public void childrenAdded(NodeMemberEvent nme) {
328 SwingUtilities.invokeLater(() -> {
334 public void childrenRemoved(NodeMemberEvent nme) {
335 SwingUtilities.invokeLater(() -> {
341 public void childrenReordered(NodeReorderEvent nre) {
346 public void nodeDestroyed(NodeEvent ne) {
351 public void propertyChange(PropertyChangeEvent evt) {
368 if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) {
369 this.getExplorerManager().setRootContext(this.rootNode);
372 Node emptyNode =
new AbstractNode(Children.LEAF);
373 this.getExplorerManager().setRootContext(emptyNode);
374 outline.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
376 outlineView.setPropertyColumns();
379 this.setCursor(null);
390 outlineView.addTreeExpansionListener(listener);
415 List<Node.Property<?>> props = loadColumnOrder();
416 boolean propsExist = props.isEmpty() ==
false;
417 Node.Property<?> firstProp = null;
419 firstProp = props.remove(0);
427 outline.setAutoResizeMode((props.isEmpty()) ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF);
429 assignColumns(props);
430 if (firstProp != null) {
431 ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(firstProp.getDisplayName());
455 loadColumnVisibility();
461 SwingUtilities.invokeLater(() -> {
463 NodeSelectionInfo selectedChildInfo = ((TableFilterNode) rootNode).getChildNodeSelectionInfo();
464 if (null != selectedChildInfo) {
465 Node[] childNodes = rootNode.getChildren().getNodes(
true);
466 for (
int i = 0; i < childNodes.length; ++i) {
467 Node childNode = childNodes[i];
468 if (selectedChildInfo.
matches(childNode)) {
470 this.getExplorerManager().setSelectedNodes(
new Node[]{childNode});
471 }
catch (PropertyVetoException ex) {
472 LOGGER.log(Level.SEVERE,
"Failed to select node specified by selected child info", ex);
477 ((TableFilterNode) rootNode).setChildNodeSelectionInfo(null);
497 TableColumnModel columnModel = outline.getColumnModel();
498 int columnCount = columnModel.getColumnCount();
500 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
501 final String propName = entry.getValue().getName();
502 if (entry.getKey() < columnCount) {
503 final ETableColumn column = (ETableColumn) columnModel.getColumn(entry.getKey());
504 columnMap.put(propName, column);
515 if (rootNode.getChildren().getNodesCount() != 0) {
516 final Graphics graphics = outlineView.getGraphics();
517 if (graphics != null) {
518 final FontMetrics metrics = graphics.getFontMetrics();
523 for (
int column = 0; column < outline.getModel().getColumnCount(); column++) {
524 int firstColumnPadding = (column == 0) ? 32 : 0;
525 int columnWidthLimit = (column == 0) ? 350 : 300;
529 for (
int row = 0; row < Math.min(100, outline.getRowCount()); row++) {
530 TableCellRenderer renderer = outline.getCellRenderer(row, column);
531 Component comp = outline.prepareRenderer(renderer, row, column);
532 valuesWidth = Math.max(comp.getPreferredSize().width, valuesWidth);
535 int headerWidth = metrics.stringWidth(outline.getColumnName(column));
536 valuesWidth += firstColumnPadding;
538 int columnWidth = Math.max(valuesWidth, headerWidth);
539 columnWidth += 2 * margin + padding;
540 columnWidth = Math.min(columnWidth, columnWidthLimit);
542 outline.getColumnModel().getColumn(column).setPreferredWidth(columnWidth);
547 outline.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
552 return outline.getColumnModel();
560 String[] propStrings =
new String[props.size() * 2];
561 for (
int i = 0; i < props.size(); i++) {
562 final Property<?> prop = props.get(i);
563 prop.setValue(
"ComparableColumnTTV", Boolean.TRUE);
566 prop.setValue(
"TreeColumnTTV", Boolean.TRUE);
567 prop.setValue(
"SortingColumnTTV", Boolean.TRUE);
569 propStrings[2 * i] = prop.getName();
570 propStrings[2 * i + 1] = prop.getDisplayName();
572 outlineView.setPropertyColumns(propStrings);
580 if (rootNode == null || propertiesMap.isEmpty()) {
584 TableFilterNode tfn = (TableFilterNode) rootNode;
586 final ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
587 for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
588 String columnName = entry.getKey();
589 final String columnHiddenKey = ResultViewerPersistence.getColumnHiddenKey(tfn, columnName);
590 final TableColumn column = entry.getValue();
591 boolean columnHidden = columnModel.isColumnHidden(column);
593 preferences.putBoolean(columnHiddenKey,
true);
595 preferences.remove(columnHiddenKey);
606 if (rootNode == null || propertiesMap.isEmpty()) {
610 TableFilterNode tfn = (TableFilterNode) rootNode;
613 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
614 preferences.putInt(ResultViewerPersistence.getColumnPositionKey(tfn, entry.getValue().getName()), entry.getKey());
623 if (rootNode == null || propertiesMap.isEmpty()) {
627 final TableFilterNode tfn = ((TableFilterNode) rootNode);
629 ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
630 for (Map.Entry<String, ETableColumn> entry : columnMap.entrySet()) {
631 ETableColumn etc = entry.getValue();
632 String columnName = entry.getKey();
634 final String columnSortOrderKey = ResultViewerPersistence.getColumnSortOrderKey(tfn, columnName);
635 final String columnSortRankKey = ResultViewerPersistence.getColumnSortRankKey(tfn, columnName);
636 if (etc.isSorted() && (columnModel.isColumnHidden(etc) ==
false)) {
637 preferences.putBoolean(columnSortOrderKey, etc.isAscending());
638 preferences.putInt(columnSortRankKey, etc.getSortRank());
640 columnModel.setColumnSorted(etc,
true, 0);
641 preferences.remove(columnSortOrderKey);
642 preferences.remove(columnSortRankKey);
655 if (rootNode == null || propertiesMap.isEmpty()) {
659 final TableFilterNode tfn = (TableFilterNode) rootNode;
662 TreeSet<ColumnSortInfo> sortInfos =
new TreeSet<>(Comparator.comparing(ColumnSortInfo::getRank));
663 propertiesMap.entrySet().stream().forEach(entry -> {
664 final String propName = entry.getValue().getName();
666 Integer sortRank = preferences.getInt(ResultViewerPersistence.getColumnSortRankKey(tfn, propName), 0);
668 Boolean sortOrder = preferences.getBoolean(ResultViewerPersistence.getColumnSortOrderKey(tfn, propName),
true);
669 sortInfos.add(
new ColumnSortInfo(entry.getKey(), sortRank, sortOrder));
672 sortInfos.forEach(sortInfo -> outline.setColumnSorted(sortInfo.modelIndex, sortInfo.order, sortInfo.rank));
681 if (rootNode == null || propertiesMap.isEmpty()) {
686 final TableFilterNode tfn = ((TableFilterNode) rootNode);
687 ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel();
688 for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
689 final String propName = entry.getValue().getName();
690 boolean hidden = preferences.getBoolean(ResultViewerPersistence.getColumnHiddenKey(tfn, propName),
false);
691 final TableColumn column = columnMap.get(propName);
692 columnModel.setColumnHidden(column, hidden);
707 List<Property<?>> props = ResultViewerPersistence.getAllChildProperties(rootNode, 100);
714 final TableFilterNode tfn = ((TableFilterNode) rootNode);
715 propertiesMap.clear();
723 int offset = props.size();
724 boolean noPreviousSettings =
true;
728 for (Property<?> prop : props) {
729 Integer value = preferences.getInt(ResultViewerPersistence.getColumnPositionKey(tfn, prop.getName()), -1);
730 if (value >= 0 && value < offset && !propertiesMap.containsKey(value)) {
731 propertiesMap.put(value, prop);
732 noPreviousSettings =
false;
734 propertiesMap.put(offset, prop);
741 if (noPreviousSettings) {
742 ArrayList<Integer> keys =
new ArrayList<>(propertiesMap.keySet());
743 for (
int key : keys) {
744 propertiesMap.put(key - props.size(), propertiesMap.remove(key));
748 return new ArrayList<>(propertiesMap.values());
757 this.outlineView.removeAll();
758 this.outlineView = null;
759 super.clearComponent();
772 this.modelIndex = modelIndex;
796 this.nodeName = nodeName;
801 if (!nodeName.isEmpty()) {
809 postPageChangeEvent();
812 void previousPage() {
814 postPageChangeEvent();
817 @NbBundle.Messages({
"# {0} - totalPages",
818 "DataResultViewerTable.goToPageTextField.msgDlg=Please enter a valid page number between 1 and {0}",
819 "DataResultViewerTable.goToPageTextField.err=Invalid page number"})
822 currentPage = Integer.decode(gotoPageTextField.getText());
823 }
catch (NumberFormatException e) {
828 if (currentPage > totalPages || currentPage < 1) {
830 JOptionPane.showMessageDialog(DataResultViewerTable.this,
831 Bundle.DataResultViewerTable_goToPageTextField_msgDlg(totalPages),
832 Bundle.DataResultViewerTable_goToPageTextField_err(),
833 JOptionPane.WARNING_MESSAGE);
836 postPageChangeEvent();
843 void postPageChangeEvent() {
845 BaseChildFactory.post(nodeName,
new PageChangeEvent(currentPage));
846 }
catch (BaseChildFactory.NoSuchEventBusException ex) {
847 LOGGER.log(Level.WARNING,
"Failed to post page change event.", ex);
849 DataResultViewerTable.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
857 void postPageSizeChangeEvent() {
861 if (
this == pagingSupport) {
865 BaseChildFactory.post(nodeName,
new PageSizeChangeEvent(UserPreferences.getResultsTablePageSize()));
866 }
catch (BaseChildFactory.NoSuchEventBusException ex) {
867 LOGGER.log(Level.WARNING,
"Failed to post page size change event.", ex);
879 totalPages =
event.getPageCount();
880 if (totalPages > 1) {
882 togglePageControls(
true);
886 if (nodeName.equals(rootNode.getName())) {
898 pageLabel.setVisible(onOff);
899 pagesLabel.setVisible(onOff);
900 pagePrevButton.setVisible(onOff);
901 pageNextButton.setVisible(onOff);
902 pageNumLabel.setVisible(onOff);
903 gotoPageLabel.setVisible(onOff);
904 gotoPageTextField.setVisible(onOff);
905 gotoPageTextField.setVisible(onOff);
910 @NbBundle.Messages({
"# {0} - currentPage",
"# {1} - totalPages",
911 "DataResultViewerTable.pageNumbers.curOfTotal={0} of {1}"})
913 if (totalPages == 0) {
914 pagePrevButton.setEnabled(
false);
915 pageNextButton.setEnabled(
false);
916 pageNumLabel.setText(
"");
917 gotoPageTextField.setText(
"");
918 gotoPageTextField.setEnabled(
false);
920 pageNumLabel.setText(Bundle.DataResultViewerTable_pageNumbers_curOfTotal(Integer.toString(currentPage), Integer.toString(totalPages)));
922 pageNextButton.setEnabled(currentPage != totalPages);
923 pagePrevButton.setEnabled(currentPage != 1);
924 gotoPageTextField.setEnabled(totalPages > 1);
925 gotoPageTextField.setText(
"");
936 @NbBundle.Messages({
"DataResultViewerTable.commentRender.name=C",
937 "DataResultViewerTable.commentRender.toolTip=C(omments) indicates whether the item has a comment",
938 "DataResultViewerTable.scoreRender.name=S",
939 "DataResultViewerTable.scoreRender.toolTip=S(core) indicates whether the item is interesting or notable",
940 "DataResultViewerTable.countRender.name=O",
941 "DataResultViewerTable.countRender.toolTip=O(ccurrences) indicates the number of data sources containing the item in the Central Repository"})
944 if (e.getSource() instanceof ETableColumnModel) {
945 TableColumn column = ((TableColumnModel) e.getSource()).getColumn(e.getToIndex());
946 if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_commentRender_name())) {
948 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_commentRender_toolTip());
950 }
else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_scoreRender_name())) {
952 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_scoreRender_toolTip());
954 }
else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_countRender_name())) {
955 outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_countRender_toolTip());
991 private class TableListener extends MouseAdapter implements TableColumnModelListener {
995 private int startColumnIndex = -1;
996 private int endColumnIndex = -1;
1001 int fromIndex = e.getFromIndex();
1002 int toIndex = e.getToIndex();
1003 if (fromIndex == toIndex) {
1017 if (startColumnIndex == -1) {
1018 startColumnIndex = fromIndex;
1020 endColumnIndex = toIndex;
1023 ArrayList<Integer> indicesList =
new ArrayList<>(propertiesMap.keySet());
1024 int leftIndex = Math.min(fromIndex, toIndex);
1025 int rightIndex = Math.max(fromIndex, toIndex);
1028 List<Integer> range = indicesList.subList(leftIndex, rightIndex + 1);
1029 int rangeSize = range.size();
1031 if (fromIndex < toIndex) {
1034 Property<?> movedProp = propertiesMap.get(range.get(0));
1035 for (
int i = 0; i < rangeSize - 1; i++) {
1036 propertiesMap.put(range.get(i), propertiesMap.get(range.get(i + 1)));
1038 propertiesMap.put(range.get(rangeSize - 1), movedProp);
1042 Property<?> movedProp = propertiesMap.get(range.get(rangeSize - 1));
1043 for (
int i = rangeSize - 1; i > 0; i--) {
1044 propertiesMap.put(range.get(i), propertiesMap.get(range.get(i - 1)));
1046 propertiesMap.put(range.get(0), movedProp);
1065 if (startColumnIndex != -1 && (startColumnIndex == 0 || endColumnIndex == 0)) {
1066 outline.moveColumn(endColumnIndex, startColumnIndex);
1068 startColumnIndex = -1;
1074 storeColumnSorting();
1079 columnAddedOrRemoved();
1084 columnAddedOrRemoved();
1093 if (listenToVisibilitEvents) {
1117 this.listenToVisibilitEvents = b;
1127 private static final long serialVersionUID = 1L;
1129 @NbBundle.Messages({
"DataResultViewerTable.commentRenderer.crComment.toolTip=Comment exists in Central Repository",
1130 "DataResultViewerTable.commentRenderer.tagComment.toolTip=Comment exists on associated tag(s)",
1131 "DataResultViewerTable.commentRenderer.crAndTagComment.toolTip=Comments exist both in Central Repository and on associated tag(s)",
1132 "DataResultViewerTable.commentRenderer.noComment.toolTip=No comments found"})
1135 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1136 setBackground(component.getBackground());
1137 setHorizontalAlignment(CENTER);
1138 Object switchValue = null;
1142 switchValue = ((Node.Property) value).getValue();
1143 }
catch (IllegalAccessException | InvocationTargetException ex) {
1148 switchValue = value;
1153 switch ((HasCommentStatus) switchValue) {
1155 setIcon(COMMENT_ICON);
1156 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_crComment_toolTip());
1159 setIcon(COMMENT_ICON);
1160 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_tagComment_toolTip());
1162 case CR_AND_TAG_COMMENTS:
1163 setIcon(COMMENT_ICON);
1164 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_crAndTagComment_toolTip());
1166 case TAG_NO_COMMENT:
1170 setToolTipText(Bundle.DataResultViewerTable_commentRenderer_noComment_toolTip());
1187 private static final long serialVersionUID = 1L;
1191 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1192 setBackground(component.getBackground());
1193 setHorizontalAlignment(CENTER);
1194 Object switchValue = null;
1198 switchValue = ((Node.Property) value).getValue();
1199 setToolTipText(((FeatureDescriptor) value).getShortDescription());
1200 }
catch (IllegalAccessException | InvocationTargetException ex) {
1206 switchValue = value;
1209 if ((switchValue instanceof
Score)) {
1211 switch ((Score) switchValue) {
1212 case INTERESTING_SCORE:
1213 setIcon(INTERESTING_SCORE_ICON);
1216 setIcon(NOTABLE_ICON_SCORE);
1236 private static final long serialVersionUID = 1L;
1240 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1241 setBackground(component.getBackground());
1242 setHorizontalAlignment(LEFT);
1243 Object countValue = null;
1247 countValue = ((Node.Property) value).getValue();
1248 setToolTipText(((FeatureDescriptor) value).getShortDescription());
1249 }
catch (IllegalAccessException | InvocationTargetException ex) {
1257 if ((countValue instanceof Long)) {
1259 if ((Long) countValue >= 0) {
1260 setText(countValue.toString());
1294 @SuppressWarnings(
"unchecked")
1296 private
void initComponents() {
1298 pageLabel =
new javax.swing.JLabel();
1299 pageNumLabel =
new javax.swing.JLabel();
1300 pagesLabel =
new javax.swing.JLabel();
1301 pagePrevButton =
new javax.swing.JButton();
1302 pageNextButton =
new javax.swing.JButton();
1304 gotoPageLabel =
new javax.swing.JLabel();
1305 gotoPageTextField =
new javax.swing.JTextField();
1306 exportCSVButton =
new javax.swing.JButton();
1308 pageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageLabel.text"));
1310 pageNumLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageNumLabel.text"));
1312 pagesLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pagesLabel.text"));
1314 pagePrevButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
1315 pagePrevButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pagePrevButton.text"));
1316 pagePrevButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
1317 pagePrevButton.setFocusable(
false);
1318 pagePrevButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
1319 pagePrevButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
1320 pagePrevButton.setPreferredSize(
new java.awt.Dimension(55, 23));
1321 pagePrevButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
1322 pagePrevButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
1323 pagePrevButton.addActionListener(
new java.awt.event.ActionListener() {
1324 public void actionPerformed(java.awt.event.ActionEvent evt) {
1325 pagePrevButtonActionPerformed(evt);
1329 pageNextButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
1330 pageNextButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.pageNextButton.text"));
1331 pageNextButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
1332 pageNextButton.setFocusable(
false);
1333 pageNextButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
1334 pageNextButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
1335 pageNextButton.setMaximumSize(
new java.awt.Dimension(27, 23));
1336 pageNextButton.setMinimumSize(
new java.awt.Dimension(27, 23));
1337 pageNextButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
1338 pageNextButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
1339 pageNextButton.addActionListener(
new java.awt.event.ActionListener() {
1340 public void actionPerformed(java.awt.event.ActionEvent evt) {
1341 pageNextButtonActionPerformed(evt);
1345 gotoPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.gotoPageLabel.text"));
1347 gotoPageTextField.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.gotoPageTextField.text"));
1348 gotoPageTextField.addActionListener(
new java.awt.event.ActionListener() {
1349 public void actionPerformed(java.awt.event.ActionEvent evt) {
1350 gotoPageTextFieldActionPerformed(evt);
1354 exportCSVButton.setText(
org.openide.util.NbBundle.getMessage(
DataResultViewerTable.class,
"DataResultViewerTable.exportCSVButton.text"));
1355 exportCSVButton.addActionListener(
new java.awt.event.ActionListener() {
1356 public void actionPerformed(java.awt.event.ActionEvent evt) {
1357 exportCSVButtonActionPerformed(evt);
1361 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
1362 this.setLayout(layout);
1363 layout.setHorizontalGroup(
1364 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1365 .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 904, Short.MAX_VALUE)
1366 .addGroup(layout.createSequentialGroup()
1368 .addComponent(pageLabel)
1369 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1370 .addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
1372 .addComponent(pagesLabel)
1373 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
1374 .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
1375 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1376 .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
1377 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
1378 .addComponent(gotoPageLabel)
1379 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1380 .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
1381 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
1382 .addComponent(exportCSVButton))
1385 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {pageNextButton, pagePrevButton});
1387 layout.setVerticalGroup(
1388 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1389 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
1391 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
1392 .addComponent(pageLabel)
1393 .addComponent(pageNumLabel)
1394 .addComponent(pagesLabel)
1395 .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
1396 .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
1397 .addComponent(gotoPageLabel)
1398 .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
1399 .addComponent(exportCSVButton))
1401 .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE)
1405 layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {pageNextButton, pagePrevButton});
1407 gotoPageLabel.getAccessibleContext().setAccessibleName(
"");
1411 pagingSupport.previousPage();
1415 pagingSupport.nextPage();
1419 pagingSupport.gotoPage();
1422 @NbBundle.Messages({
"DataResultViewerTable.exportCSVButtonActionPerformed.empty=No data to export"
1425 Node currentRoot = this.getExplorerManager().getRootContext();
1426 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 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)