protected JTree createTree() {
    Tree internalTree = createInternalTree();
    myFileSystemTree = new FileSystemTreeImpl(myProject, myChooserDescriptor, internalTree, null, null, null);
    internalTree.setRootVisible(myChooserDescriptor.isTreeRootVisible());
    internalTree.setShowsRootHandles(true);
    Disposer.register(getDisposable(), myFileSystemTree);

    myFileSystemTree.addOkAction(this::doOKAction);
    JTree tree = myFileSystemTree.getTree();
    if (!Registry.is("file.chooser.async.tree.model")) tree.setCellRenderer(new NodeRenderer());
    tree.getSelectionModel().addTreeSelectionListener(new FileTreeSelectionListener());
    tree.addTreeExpansionListener(new FileTreeExpansionListener());
    setOKActionEnabled(false);

    myFileSystemTree.addListener(selection -> {
      // myTreeIsUpdating makes no sense for AsyncTreeModel
      if (myTreeIsUpdating) myTreeIsUpdating = false;
      updatePathFromTree(selection, false);
    }, getDisposable());

    new FileDrop(tree, new FileDrop.Target() {
      @Override
      public FileChooserDescriptor getDescriptor() {
        return myChooserDescriptor;
      }

      @Override
      public boolean isHiddenShown() {
        return myFileSystemTree.areHiddensShown();
      }

      @Override
      public void dropFiles(final List<? extends VirtualFile> files) {
        if (!myChooserDescriptor.isChooseMultiple() && !files.isEmpty()) {
          selectInTree(new VirtualFile[]{files.get(0)}, true, true);
        }
        else {
          selectInTree(VfsUtilCore.toVirtualFileArray(files), true, true);
        }
      }
    });

    return tree;
  }
protected JTree createTree()