19 package org.sleuthkit.autopsy.corecomponents;
21 import java.awt.Cursor;
22 import java.awt.FontMetrics;
23 import java.awt.Graphics;
24 import java.awt.dnd.DnDConstants;
25 import java.beans.PropertyChangeEvent;
26 import java.lang.reflect.InvocationTargetException;
27 import java.util.ArrayList;
28 import java.util.LinkedHashSet;
29 import java.util.List;
31 import javax.swing.JTable;
32 import javax.swing.ListSelectionModel;
33 import javax.swing.SwingUtilities;
34 import org.netbeans.swing.outline.DefaultOutlineModel;
35 import org.openide.explorer.ExplorerManager;
36 import org.openide.explorer.view.OutlineView;
37 import org.openide.nodes.AbstractNode;
38 import org.openide.nodes.Children;
39 import org.openide.nodes.Node;
40 import org.openide.nodes.Node.Property;
41 import org.openide.nodes.Node.PropertySet;
42 import org.openide.nodes.NodeEvent;
43 import org.openide.nodes.NodeListener;
44 import org.openide.nodes.NodeMemberEvent;
45 import org.openide.nodes.NodeReorderEvent;
46 import org.openide.nodes.Sheet;
47 import org.openide.util.NbBundle;
69 super(explorerManager);
85 ov.setAllowedDragActions(DnDConstants.ACTION_NONE);
86 ov.setAllowedDropActions(DnDConstants.ACTION_NONE);
88 ov.getOutline().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
91 ov.getOutline().setRootVisible(
false);
92 ov.getOutline().setDragEnabled(
false);
115 @SuppressWarnings(
"unchecked")
122 tableScrollPanel.addComponentListener(
new java.awt.event.ComponentAdapter() {
123 public void componentResized(java.awt.event.ComponentEvent evt) {
128 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
129 this.setLayout(layout);
130 layout.setHorizontalGroup(
131 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
132 .addComponent(
tableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 691, Short.MAX_VALUE)
134 layout.setVerticalGroup(
135 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
136 .addComponent(
tableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 366, Short.MAX_VALUE)
153 Node firstChild = parent.getChildren().getNodeAt(0);
155 if (firstChild == null) {
156 throw new IllegalArgumentException(
157 NbBundle.getMessage(
this.getClass(),
"DataResultViewerTable.illegalArgExc.noChildFromParent"));
159 for (PropertySet ps : firstChild.getPropertySets()) {
160 if (ps.getName().equals(Sheet.PROPERTIES)) {
161 return ps.getProperties();
165 throw new IllegalArgumentException(
166 NbBundle.getMessage(
this.getClass(),
"DataResultViewerTable.illegalArgExc.childWithoutPropertySet"));
178 @SuppressWarnings(
"rawtypes")
180 Node firstChild = parent.getChildren().getNodeAt(0);
182 Property[] properties = null;
184 if (firstChild == null) {
185 throw new IllegalArgumentException(
186 NbBundle.getMessage(
this.getClass(),
"DataResultViewerTable.illegalArgExc.noChildFromParent"));
188 Set<Property> allProperties =
new LinkedHashSet<Property>();
189 while (firstChild != null) {
190 for (PropertySet ps : firstChild.getPropertySets()) {
193 final Property[] props = ps.getProperties();
194 final int propsNum = props.length;
195 for (
int i = 0; i < propsNum; ++i) {
196 allProperties.add(props[i]);
200 firstChild = firstChild.getChildren().getNodeAt(0);
203 properties = allProperties.toArray(
new Property[0]);
220 Children children = parent.getChildren();
222 for (Node child : children.getNodes()) {
223 if (++childCount > rows) {
226 for (PropertySet ps : child.getPropertySets()) {
227 final Property<?>[] props = ps.getProperties();
228 final int propsNum = props.length;
229 for (
int j = 0; j < propsNum; ++j) {
230 propertiesAcc.add(props[j]);
251 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
253 boolean hasChildren =
false;
255 if (selectedNode != null) {
257 hasChildren = selectedNode.getChildren().getNodesCount() > 0;
260 Node oldNode = this.em.getRootContext();
261 if (oldNode != null) {
262 oldNode.removeNodeListener(dummyNodeListener);
267 Node root = selectedNode;
268 dummyNodeListener.
reset();
269 root.addNodeListener(dummyNodeListener);
273 Node emptyNode =
new AbstractNode(Children.LEAF);
274 em.setRootContext(emptyNode);
275 ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
276 ov.setPropertyColumns();
279 this.setCursor(null);
297 em.setRootContext(root);
306 propertiesAcc.clear();
309 List<Node.Property<?>> props =
new ArrayList<>(
propertiesAcc);
319 if (props.size() > 0) {
320 Node.Property<?> prop = props.remove(0);
321 ((DefaultOutlineModel) ov.getOutline().getOutlineModel()).setNodesColumnLabel(prop.getDisplayName());
326 String[] propStrings =
new String[props.size() * 2];
327 for (
int i = 0; i < props.size(); i++) {
328 props.get(i).setValue(
"ComparableColumnTTV", Boolean.TRUE);
331 props.get(i).setValue(
"TreeColumnTTV", Boolean.TRUE);
332 props.get(i).setValue(
"SortingColumnTTV", Boolean.TRUE);
334 propStrings[2 * i] = props.get(i).getName();
335 propStrings[2 * i + 1] = props.get(i).getDisplayName();
338 ov.setPropertyColumns(propStrings);
351 int totalColumns = props.size();
359 ov.getOutline().setAutoResizeMode((props.size() > 0) ? JTable.AUTO_RESIZE_OFF : JTable.AUTO_RESIZE_ALL_COLUMNS);
364 Object[][] content = null;
368 if (content != null) {
370 final Graphics graphics = ov.getGraphics();
371 if (graphics != null) {
372 final FontMetrics metrics = graphics.getFontMetrics();
375 int nodeColWidth = Math.min(
getMaxColumnWidth(0, metrics, margin, 40, firstColumnLabel, content), 250);
376 ov.getOutline().getColumnModel().getColumn(0).setPreferredWidth(nodeColWidth);
379 for (
int colIndex = startColumn; colIndex <= totalColumns; colIndex++) {
380 int colWidth = Math.min(
getMaxColumnWidth(colIndex, metrics, margin, 8, props, content), 350);
381 ov.getOutline().getColumnModel().getColumn(colIndex).setPreferredWidth(colWidth);
387 if (!(content.length > 0)) {
389 ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
396 int numRows = Math.min(maxRows, node.getChildren().getNodesCount());
397 Object[][] rowValues =
new Object[numRows][];
399 for (Node child : node.getChildren().getNodes()) {
400 if (rowCount >= maxRows) {
408 if (rowCount > numRows) {
411 PropertySet[] propertySets = child.getPropertySets();
412 if (propertySets.length > 0) {
413 Property<?>[] properties = propertySets[0].getProperties();
414 rowValues[rowCount] =
new Object[properties.length];
415 for (
int j = 0; j < properties.length; ++j) {
417 rowValues[rowCount][j] = properties[j].getValue();
418 }
catch (IllegalAccessException | InvocationTargetException ignore) {
419 rowValues[rowCount][j] =
"n/a";
430 return NbBundle.getMessage(this.getClass(),
"DataResultViewerTable.title");
449 @SuppressWarnings(
"rawtypes")
450 private
int getMaxColumnWidth(
int index, FontMetrics metrics,
int margin,
int padding, List<Node.Property<?>> header, Object[][] table) {
452 String headerName = header.get(index - 1).getDisplayName();
468 private synchronized int getMaxColumnWidth(
int index, FontMetrics metrics,
int margin,
int padding, String header, Object[][] table) {
470 String headerName = header;
471 int headerWidth = metrics.stringWidth(headerName);
475 for (
int i = 0; i < table.length; i++) {
476 if (table[i] == null || index >= table[i].length) {
479 String test = table[i][index].toString();
480 colWidth = Math.max(colWidth, metrics.stringWidth(test));
487 int width = Math.max(headerWidth, colWidth);
498 super.clearComponent();
503 private volatile boolean load =
true;
511 Node[] delta = nme.getDelta();
514 if (SwingUtilities.isEventDispatchThread()) {
517 SwingUtilities.invokeLater(
new Runnable() {
528 for (Node n : delta) {
529 if (!n.getDisplayName().equals(DUMMY_NODE_DISPLAY_NAME)) {
Set< Property<?> > propertiesAcc
void childrenReordered(NodeReorderEvent nre)
final DummyNodeListener dummyNodeListener
void getAllChildPropertyHeadersRec(Node parent, int rows)
void propertyChange(PropertyChangeEvent evt)
void tableScrollPanelComponentResized(java.awt.event.ComponentEvent evt)
int getMaxColumnWidth(int index, FontMetrics metrics, int margin, int padding, List< Node.Property<?>> header, Object[][] table)
boolean isSupported(Node selectedNode)
DataResultViewer createInstance()
void childrenRemoved(NodeMemberEvent nme)
void nodeDestroyed(NodeEvent ne)
static Object[][] getRowValues(Node node, int maxRows)
boolean containsReal(Node[] delta)
synchronized int getMaxColumnWidth(int index, FontMetrics metrics, int margin, int padding, String header, Object[][] table)
void childrenAdded(final NodeMemberEvent nme)
void setNode(Node selectedNode)
Node.Property<?>[] getChildPropertyHeaders(Node parent)
Node.Property[] getAllChildPropertyHeaders(Node parent)
static final String DUMMY_NODE_DISPLAY_NAME
DataResultViewerTable(ExplorerManager explorerManager)
void setupTable(final Node root)
javax.swing.JScrollPane tableScrollPanel