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.awt.event.MouseEvent;
26 import java.awt.event.MouseListener;
27 import java.beans.PropertyChangeEvent;
28 import java.lang.reflect.InvocationTargetException;
29 import java.util.ArrayList;
30 import java.util.LinkedHashSet;
31 import java.util.List;
33 import javax.swing.Action;
34 import javax.swing.JTable;
35 import javax.swing.ListSelectionModel;
36 import javax.swing.SwingUtilities;
37 import org.netbeans.swing.outline.DefaultOutlineModel;
38 import org.openide.explorer.ExplorerManager;
39 import org.openide.explorer.view.OutlineView;
40 import org.openide.nodes.AbstractNode;
41 import org.openide.nodes.Children;
42 import org.openide.nodes.Node;
43 import org.openide.nodes.Node.Property;
44 import org.openide.nodes.Node.PropertySet;
45 import org.openide.nodes.NodeEvent;
46 import org.openide.nodes.NodeListener;
47 import org.openide.nodes.NodeMemberEvent;
48 import org.openide.nodes.NodeReorderEvent;
49 import org.openide.nodes.Sheet;
50 import org.openide.util.NbBundle;
73 super(explorerManager);
89 ov.setAllowedDragActions(DnDConstants.ACTION_NONE);
91 ov.getOutline().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
94 ov.getOutline().setRootVisible(
false);
95 ov.getOutline().setDragEnabled(
false);
147 @SuppressWarnings(
"unchecked")
154 tableScrollPanel.addComponentListener(
new java.awt.event.ComponentAdapter() {
155 public void componentResized(java.awt.event.ComponentEvent evt) {
160 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
161 this.setLayout(layout);
162 layout.setHorizontalGroup(
163 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
164 .addComponent(
tableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 691, Short.MAX_VALUE)
166 layout.setVerticalGroup(
167 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
168 .addComponent(
tableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 366, Short.MAX_VALUE)
186 Node firstChild = parent.getChildren().getNodeAt(0);
188 if (firstChild == null) {
189 throw new IllegalArgumentException(
190 NbBundle.getMessage(
this.getClass(),
"DataResultViewerTable.illegalArgExc.noChildFromParent"));
192 for (PropertySet ps : firstChild.getPropertySets()) {
193 if (ps.getName().equals(Sheet.PROPERTIES)) {
194 return ps.getProperties();
198 throw new IllegalArgumentException(
199 NbBundle.getMessage(
this.getClass(),
"DataResultViewerTable.illegalArgExc.childWithoutPropertySet"));
212 @SuppressWarnings(
"rawtypes")
214 Node firstChild = parent.getChildren().getNodeAt(0);
216 Property[] properties = null;
218 if (firstChild == null) {
219 throw new IllegalArgumentException(
220 NbBundle.getMessage(
this.getClass(),
"DataResultViewerTable.illegalArgExc.noChildFromParent"));
222 Set<Property> allProperties =
new LinkedHashSet<>();
223 while (firstChild != null) {
224 for (PropertySet ps : firstChild.getPropertySets()) {
225 final Property[] props = ps.getProperties();
226 final int propsNum = props.length;
227 for (
int i = 0; i < propsNum; ++i) {
228 allProperties.add(props[i]);
231 firstChild = firstChild.getChildren().getNodeAt(0);
234 properties = allProperties.toArray(
new Property<?>[0]);
250 Children children = parent.getChildren();
252 for (Node child : children.getNodes()) {
253 if (++childCount > rows) {
256 for (PropertySet ps : child.getPropertySets()) {
257 final Property<?>[] props = ps.getProperties();
258 final int propsNum = props.length;
259 for (
int j = 0; j < propsNum; ++j) {
260 propertiesAcc.add(props[j]);
281 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
283 boolean hasChildren =
false;
285 if (selectedNode != null) {
287 hasChildren = selectedNode.getChildren().getNodesCount() > 0;
290 Node oldNode = this.em.getRootContext();
291 if (oldNode != null) {
292 oldNode.removeNodeListener(dummyNodeListener);
297 Node root = selectedNode;
298 dummyNodeListener.
reset();
299 root.addNodeListener(dummyNodeListener);
303 Node emptyNode =
new AbstractNode(Children.LEAF);
304 em.setRootContext(emptyNode);
305 ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
306 ov.setPropertyColumns();
309 this.setCursor(null);
321 em.setRootContext(root);
339 propertiesAcc.clear();
341 List<Node.Property<?>> props =
new ArrayList<>(
propertiesAcc);
354 if (props.size() > 0) {
355 Node.Property<?> prop = props.remove(0);
356 ((DefaultOutlineModel) ov.getOutline().getOutlineModel()).setNodesColumnLabel(prop.getDisplayName());
360 String[] propStrings =
new String[props.size() * 2];
361 for (
int i = 0; i < props.size(); i++) {
362 props.get(i).setValue(
"ComparableColumnTTV", Boolean.TRUE);
365 props.get(i).setValue(
"TreeColumnTTV", Boolean.TRUE);
366 props.get(i).setValue(
"SortingColumnTTV", Boolean.TRUE);
368 propStrings[2 * i] = props.get(i).getName();
369 propStrings[2 * i + 1] = props.get(i).getDisplayName();
372 ov.setPropertyColumns(propStrings);
375 int totalColumns = props.size();
383 ov.getOutline().setAutoResizeMode((props.size() > 0) ? JTable.AUTO_RESIZE_OFF : JTable.AUTO_RESIZE_ALL_COLUMNS);
389 if (content != null) {
391 final Graphics graphics = ov.getGraphics();
392 if (graphics != null) {
393 final FontMetrics metrics = graphics.getFontMetrics();
396 int nodeColWidth = Math.min(
getMaxColumnWidth(0, metrics, margin, 40, firstColumnLabel, content), 250);
397 ov.getOutline().getColumnModel().getColumn(0).setPreferredWidth(nodeColWidth);
400 for (
int colIndex = startColumn; colIndex <= totalColumns; colIndex++) {
401 int colWidth = Math.min(
getMaxColumnWidth(colIndex, metrics, margin, 8, props, content), 350);
402 ov.getOutline().getColumnModel().getColumn(colIndex).setPreferredWidth(colWidth);
407 if (content.length <= 0) {
409 ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
481 int numRows = Math.min(maxRows, node.getChildren().getNodesCount());
482 Object[][] rowValues =
new Object[numRows][];
484 for (Node child : node.getChildren().getNodes()) {
485 if (rowCount >= maxRows) {
493 if (rowCount > numRows) {
496 PropertySet[] propertySets = child.getPropertySets();
497 if (propertySets.length > 0) {
498 Property<?>[] properties = propertySets[0].getProperties();
499 rowValues[rowCount] =
new Object[properties.length];
500 for (
int j = 0; j < properties.length; ++j) {
502 rowValues[rowCount][j] = properties[j].getValue();
503 }
catch (IllegalAccessException | InvocationTargetException ignore) {
504 rowValues[rowCount][j] =
"n/a";
515 return NbBundle.getMessage(this.getClass(),
"DataResultViewerTable.title");
535 @SuppressWarnings(
"rawtypes")
536 private
int getMaxColumnWidth(
int index, FontMetrics metrics,
int margin,
int padding, List<Node.Property<?>> header, Object[][] table) {
538 String headerName = header.get(index - 1).getDisplayName();
555 private synchronized int getMaxColumnWidth(
int index, FontMetrics metrics,
int margin,
int padding, String header, Object[][] table) {
557 String headerName = header;
558 int headerWidth = metrics.stringWidth(headerName);
562 for (
int i = 0; i < table.length; i++) {
563 if (table[i] == null || index >= table[i].length) {
566 String test = table[i][index].toString();
567 colWidth = Math.max(colWidth, metrics.stringWidth(test));
574 int width = Math.max(headerWidth, colWidth);
585 super.clearComponent();
590 private volatile boolean load =
true;
598 Node[] delta = nme.getDelta();
601 if (SwingUtilities.isEventDispatchThread()) {
604 SwingUtilities.invokeLater(
new Runnable() {
615 for (Node n : delta) {
616 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