19 package org.sleuthkit.autopsy.communications.relationships;
 
   21 import java.awt.Component;
 
   22 import java.awt.KeyboardFocusManager;
 
   23 import java.beans.PropertyChangeEvent;
 
   24 import java.beans.PropertyChangeListener;
 
   25 import javax.swing.JPanel;
 
   26 import static javax.swing.SwingUtilities.isDescendingFrom;
 
   27 import org.netbeans.swing.outline.DefaultOutlineModel;
 
   28 import org.netbeans.swing.outline.Outline;
 
   29 import org.openide.explorer.ExplorerManager;
 
   30 import static org.openide.explorer.ExplorerUtils.createLookup;
 
   31 import org.openide.nodes.AbstractNode;
 
   32 import org.openide.nodes.Children;
 
   33 import org.openide.nodes.Node;
 
   34 import org.openide.nodes.NodeAdapter;
 
   35 import org.openide.nodes.NodeMemberEvent;
 
   36 import org.openide.util.Lookup;
 
   37 import org.openide.util.NbBundle;
 
   38 import org.openide.util.lookup.ServiceProvider;
 
   48 final class ContactsViewer 
extends JPanel implements RelationshipsViewer {
 
   50     private static final long serialVersionUID = 1L;
 
   52     private final Outline outline;
 
   53     private final ModifiableProxyLookup proxyLookup;
 
   54     private PropertyChangeListener focusPropertyListener;
 
   55     private final ContactsChildNodeFactory nodeFactory;
 
   56     private final ContactDataViewer contactPane;
 
   59         "ContactsViewer_tabTitle=Contacts",
 
   60         "ContactsViewer_columnHeader_Name=Name",
 
   61         "ContactsViewer_columnHeader_Phone=Phone",
 
   62         "ContactsViewer_columnHeader_Email=Email",
 
   63         "ContactsViewer_noContacts_message=<No contacts found for selected account>" 
   72         contactPane = 
new ContactDataViewer();
 
   73         splitPane.setRightComponent(contactPane);
 
   75         outlineViewPanel.hideOutlineView(Bundle.ContactsViewer_noContacts_message());
 
   77         proxyLookup = 
new ModifiableProxyLookup(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
 
   78         nodeFactory = 
new ContactsChildNodeFactory(null);
 
   80         outline = outlineViewPanel.getOutlineView().getOutline();
 
   81         outlineViewPanel.getOutlineView().setPropertyColumns(
 
   82                 "TSK_EMAIL", BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL.getDisplayName(),
 
   83                 "TSK_PHONE_NUMBER", BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getDisplayName()
 
   85         outline.setRootVisible(
false);
 
   86         ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.ContactsViewer_columnHeader_Name());
 
   88         outlineViewPanel.hideOutlineView(
"<No contacts for selected account>");
 
   90         outlineViewPanel.getExplorerManager().addPropertyChangeListener((PropertyChangeEvent evt) -> {
 
   91             if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) {
 
   92                 final Node[] nodes = outlineViewPanel.getExplorerManager().getSelectedNodes();
 
   93                 contactPane.setNode(nodes != null && nodes.length > 0 ? nodes[0] : null);
 
   97         outlineViewPanel.getExplorerManager().setRootContext(
new TableFilterNode(
new DataResultFilterNode(
new AbstractNode(Children.create(nodeFactory, 
true)), outlineViewPanel.getExplorerManager()), 
true));
 
  101         outlineViewPanel.getExplorerManager().getRootContext().addNodeListener(
new NodeAdapter() {
 
  103             public void childrenAdded(NodeMemberEvent nme) {
 
  104                 updateOutlineViewPanel();
 
  108             public void childrenRemoved(NodeMemberEvent nme) {
 
  109                 updateOutlineViewPanel();
 
  113         splitPane.setResizeWeight(0.5);
 
  114         splitPane.setDividerLocation(0.5);
 
  118     public String getDisplayName() {
 
  119         return Bundle.ContactsViewer_tabTitle();
 
  123     public JPanel getPanel() {
 
  128     public void setSelectionInfo(SelectionInfo info) {
 
  129         nodeFactory.refresh(info);
 
  133     public Lookup getLookup() {
 
  138     public void addNotify() {
 
  141         if (focusPropertyListener == null) {
 
  144             focusPropertyListener = (
final PropertyChangeEvent focusEvent) -> {
 
  145                 if (focusEvent.getPropertyName().equalsIgnoreCase(
"focusOwner")) {
 
  146                     handleFocusChange((Component) focusEvent.getNewValue());
 
  152         KeyboardFocusManager.getCurrentKeyboardFocusManager()
 
  153                 .addPropertyChangeListener(
"focusOwner", focusPropertyListener); 
 
  161     private void handleFocusChange(Component newFocusOwner) {
 
  162         if (newFocusOwner == null) {
 
  165         if (isDescendingFrom(newFocusOwner, contactPane)) {
 
  167             proxyLookup.setNewLookups(createLookup(contactPane.getExplorerManager(), getActionMap()));
 
  168         } 
else if (isDescendingFrom(newFocusOwner, 
this)) {
 
  170             proxyLookup.setNewLookups(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
 
  176     public void removeNotify() {
 
  177         super.removeNotify();
 
  178         if (focusPropertyListener != null) {
 
  179             KeyboardFocusManager.getCurrentKeyboardFocusManager()
 
  180                     .removePropertyChangeListener(
"focusOwner", focusPropertyListener); 
 
  184     private void updateOutlineViewPanel() {
 
  185         int nodeCount = outlineViewPanel.getExplorerManager().getRootContext().getChildren().getNodesCount();
 
  186         if (nodeCount == 0) {
 
  187             outlineViewPanel.hideOutlineView(Bundle.ContactsViewer_noContacts_message());
 
  189             outlineViewPanel.showOutlineView();
 
  198     @SuppressWarnings(
"unchecked")
 
  200     private 
void initComponents() {
 
  201         java.awt.GridBagConstraints gridBagConstraints;
 
  203         splitPane = 
new javax.swing.JSplitPane();
 
  206         setLayout(
new java.awt.GridBagLayout());
 
  208         splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
 
  209         splitPane.setLeftComponent(outlineViewPanel);
 
  211         gridBagConstraints = 
new java.awt.GridBagConstraints();
 
  212         gridBagConstraints.gridx = 0;
 
  213         gridBagConstraints.gridy = 0;
 
  214         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
 
  215         gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
 
  216         gridBagConstraints.weightx = 1.0;
 
  217         gridBagConstraints.weighty = 1.0;
 
  218         add(splitPane, gridBagConstraints);
 
  224     private javax.swing.JSplitPane splitPane;