private void setColumnsData() {
    TableColumnModel colModel = fieldsListTable.getColumnModel();

    fieldsListTable.setTreeCellRenderer(treeCellRenderer);

    for (int i = 0; i < fieldsListTableModel.getColumnCount(); i++) {
      int index = fieldsListTableModel.getRealColumn(i);

      if (index != 0) {
        colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);
        colModel.getColumn(i).setCellRenderer(columnRenderers[index]);
      }
    }
  }
  private void performDefaultAction() {
    int row = fieldsListTable.getSelectedRow();

    if (row != -1) {
      HeapWalkerNode node =
          (HeapWalkerNode) fieldsListTable.getTree().getPathForRow(row).getLastPathComponent();

      if (node instanceof HeapWalkerInstanceNode) {
        referencesBrowserController.createNavigationHistoryPoint();

        HeapWalkerInstanceNode instanceNode = (HeapWalkerInstanceNode) node;
        referencesBrowserController.navigateToInstance(instanceNode.getInstance());
      }
    }
  }
  private void selectPath(final CCTNode[] path, final int length) {
    if (length >= path.length) {
      final CCTNode node = (CCTNode) new TreePath(path).getLastPathComponent();

      // --- #208900 make sure the row is visible even if displaying a scrollbar
      fieldsListTable.selectNode(node, true);
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              fieldsListTable.selectNode(node, true);
            }
          });
      // ---
    } else {
      Object[] shortPath = new Object[length];
      System.arraycopy(path, 0, shortPath, 0, length);
      final TreePath p = new TreePath(shortPath);
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              selectPath(path, length + MAX_STEP);
            }
          });
    }
  }
  public void selectNode(HeapWalkerNode node) {
    CCTNode[] pathArr = fieldsListTable.getPathToRoot(node);
    //        System.err.println(">>> About to open path size: " + pathArr.length);

    selectPath(pathArr, Math.min(pathArr.length, MAX_STEP));

    //        fieldsListTable.selectNode(node, true);
  }
  private void saveColumnsData() {
    TableColumnModel colModel = fieldsListTable.getColumnModel();

    for (int i = 0; i < fieldsListTableModel.getColumnCount(); i++) {
      int index = fieldsListTableModel.getRealColumn(i);

      if (index != 0) {
        columnWidths[index - 1] = colModel.getColumn(i).getPreferredWidth();
      }
    }
  }
  // --- Public interface ------------------------------------------------------
  public void update() {
    if (isShowing()) {
      initData();

      if (contents != null) { // ui already initialized

        if ((fieldsListTableModel.getRoot() == null)
            || (fieldsListTableModel.getRoot()
                == ReferencesBrowserController.EMPTY_INSTANCE_NODE)) {
          contents.show(getContentPanel(), NO_DATA);
        } else {
          contents.show(getContentPanel(), DATA);
        }

        fieldsListTable
            .resetTreeCellOffsetX(); // Ideally should be invoked directly on the component when
        // root node changes
      }

      needsUpdate = false;
    } else {
      needsUpdate = true;
    }
  }
  private void showPopupMenu(int row, int x, int y) {
    HeapWalkerNode node =
        (HeapWalkerNode) fieldsListTable.getTree().getPathForRow(row).getLastPathComponent();

    if (node instanceof HeapWalkerInstanceNode && ((HeapWalkerInstanceNode) node).isLoop()) {
      showLoopOriginItem.setVisible(true);
    } else {
      showLoopOriginItem.setVisible(false);
    }

    if (node.isRoot()) {
      showInstanceItem.setEnabled(false);
      copyPathFromRootItem.setEnabled(false);
    } else {
      showInstanceItem.setEnabled(
          node instanceof HeapWalkerInstanceNode
              && !(node instanceof HeapWalkerFieldNode && ((HeapWalkerFieldNode) node).isStatic()));
      copyPathFromRootItem.setEnabled(true);
    }

    //        showClassItem.setEnabled(node instanceof HeapWalkerInstanceNode || node instanceof
    // ClassNode);
    showGcRootItem.setEnabled(
        node instanceof HeapWalkerInstanceNode
            && (!node.currentlyHasChildren()
                || (node.getNChildren() != 1
                    || !HeapWalkerNodeFactory.isMessageNode(node.getChild(0))))); // #124306
    if (showSourceItem != null) showSourceItem.setEnabled(node instanceof HeapWalkerInstanceNode);
    showInThreadsItem.setEnabled(false);
    if (node instanceof HeapWalkerInstanceNode) {
      Instance rootInstance = ((HeapWalkerInstanceNode) node).getInstance();
      Heap heap =
          referencesBrowserController
              .getReferencesControllerHandler()
              .getHeapFragmentWalker()
              .getHeapFragment();
      GCRoot gcRoot = heap.getGCRoot(rootInstance);

      if (gcRoot != null && GCRoot.JAVA_FRAME.equals(gcRoot.getKind())) {
        // make sure that thread information is available
        JavaFrameGCRoot frameVar = (JavaFrameGCRoot) gcRoot;

        if (frameVar.getFrameNumber() != -1) {
          showInThreadsItem.setEnabled(true);
        }
      }
    }

    if ((x == -1) || (y == -1)) {
      Rectangle rowBounds = fieldsListTable.getCellRect(row, 0, true);

      if (x == -1) {
        x = rowBounds.x + (rowBounds.width / 2);
      }

      if (y == -1) {
        y = rowBounds.y + (rowBounds.height / 2);
      }
    }

    tablePopup.show(fieldsListTable, x, y);
  }
  private void initComponents() {
    treeCellRenderer.setLeafIcon(null);
    treeCellRenderer.setClosedIcon(null);
    treeCellRenderer.setOpenIcon(null);

    fieldsListTableModel.setRealColumnVisibility(2, false);
    fieldsListTableModel.setRealColumnVisibility(4, false);

    if (retainedSizeSupported)
      fieldsListTableModel.setRealColumnVisibility(
          5,
          referencesBrowserController
                  .getReferencesControllerHandler()
                  .getHeapFragmentWalker()
                  .getRetainedSizesStatus()
              == HeapFragmentWalker.RETAINED_SIZES_COMPUTED);

    fieldsListTable =
        new JTreeTable(fieldsListTableModel) {
          public void doLayout() {
            int columnsWidthsSum = 0;
            int realFirstColumn = -1;

            TableColumnModel colModel = getColumnModel();

            for (int i = 0; i < fieldsListTableModel.getColumnCount(); i++) {
              if (fieldsListTableModel.getRealColumn(i) == 0) {
                realFirstColumn = i;
              } else {
                columnsWidthsSum += colModel.getColumn(i).getPreferredWidth();
              }
            }

            if (realFirstColumn != -1) {
              colModel.getColumn(realFirstColumn).setPreferredWidth(getWidth() - columnsWidthsSum);
            }

            super.doLayout();
          }
        };
    fieldsListTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    fieldsListTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);
    fieldsListTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);
    fieldsListTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);
    fieldsListTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);
    fieldsListTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);
    fieldsListTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);
    fieldsListTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);
    fieldsListTable.getTree().setLargeModel(true);
    fieldsListTable.getTree().setToggleClickCount(0);
    fieldsListTable.getColumnModel().getColumn(0).setMinWidth(150);
    fieldsListTable
        .getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "DEFAULT_ACTION"); // NOI18N
    fieldsListTable
        .getActionMap()
        .put(
            "DEFAULT_ACTION", // NOI18N
            new AbstractAction() {
              public void actionPerformed(ActionEvent e) {
                performDefaultAction();
              }
            });

    // Disable traversing table cells using TAB and Shift+TAB
    Set keys =
        new HashSet(
            fieldsListTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
    keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
    fieldsListTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);

    keys =
        new HashSet(
            fieldsListTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
    keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));
    fieldsListTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);

    setColumnsData();

    tablePopup = createTablePopup();

    cornerPopup = new JPopupMenu();

    JTreeTablePanel tablePanel = new JTreeTablePanel(fieldsListTable);
    tablePanel.setCorner(
        JScrollPane.UPPER_RIGHT_CORNER, createHeaderPopupCornerButton(cornerPopup));

    dataPanel = new JPanel(new BorderLayout());
    dataPanel.add(tablePanel, BorderLayout.CENTER);

    noDataPanel = new JPanel(new BorderLayout());
    noDataPanel.setBorder(BorderFactory.createLoweredBevelBorder());

    HTMLTextArea hintArea = new HTMLTextArea();
    hintArea.setBorder(BorderFactory.createEmptyBorder(10, 8, 8, 8));

    String instancesRes = Icons.getResource(HeapWalkerIcons.INSTANCES);
    String hintText =
        Bundle.ReferencesBrowserControllerUI_NoInstanceSelectedMsg(
            "<img border='0' align='bottom' src='nbresloc:/" + instancesRes + "'>"); // NOI18N

    hintArea.setText(hintText);
    noDataPanel.add(hintArea, BorderLayout.CENTER);

    contents = new CardLayout();
    setLayout(contents);
    add(noDataPanel, NO_DATA);
    add(dataPanel, DATA);

    fieldsListTable.addMouseListener(new FieldsListTableMouseListener());
    fieldsListTable.addKeyListener(new FieldsListTableKeyListener());
  }
 // --- Internal interface ----------------------------------------------------
 public void refreshView() {
   // Used for refreshing treetable after lazy-populating the model
   if (fieldsListTable != null) {
     fieldsListTable.updateTreeTable();
   }
 }