/** Updates the user message based on the current state of the application. */
  private void updateMessages() {
    browseStatusPanel.setBrowseStatus(browseStatus);

    if (!lifeCycleComplete) {
      messageLabel.setText(
          I18n.tr("LimeWire will start your search right after it finishes loading."));
      messagePanel.setVisible(true);
      browseFailedPanel.setVisible(false);
    } else if (!fullyConnected) {
      messageLabel.setText(
          I18n.tr("You might not receive many results until LimeWire finishes loading..."));
      messagePanel.setVisible(true);
      browseFailedPanel.setVisible(false);
    } else if (browseStatus != null && !browseStatus.getState().isOK()) {
      browseFailedPanel.update(
          browseStatus.getState(), browseStatus.getBrowseSearch(), browseStatus.getFailedFriends());
      browseFailedPanel.setVisible(true);
    } else {
      messagePanel.setVisible(false);
      browseFailedPanel.setVisible(false);
    }

    filterPanel.setVisible(!browseFailedPanel.isVisible());
    scrollPane.setVisible(!browseFailedPanel.isVisible());
  }
 /**
  * Disposes of resources used by the container. This method is called when the search is closed.
  */
 @Override
 public void dispose() {
   SwingUiSettings.SEARCH_VIEW_TYPE_ID.removeSettingListener(viewTypeListener);
   searchResultsModel.getFilteredList().removeListEventListener(resultCountListener);
   searchResultsModel.getUnfilteredList().removeListEventListener(resultCountListener);
   sortAndFilterPanel.dispose();
   filterPanel.dispose();
   classicSearchReminderPanel.dispose();
   browseFailedPanel.dispose();
   searchResultsModel.dispose();
   browseStatusPanel.dispose();
 }
  /** Constructs a SearchResultsPanel with the specified components. */
  @Inject
  public SearchResultsPanel(
      @Assisted SearchResultsModel searchResultsModel,
      ResultsContainerFactory containerFactory,
      SortAndFilterPanelFactory sortAndFilterFactory,
      AdvancedFilterPanelFactory<VisualSearchResult> filterPanelFactory,
      SponsoredResultsPanel sponsoredResultsPanel,
      HeaderBarDecorator headerBarDecorator,
      CategoryIconManager categoryIconManager,
      BrowseFailedMessagePanelFactory browseFailedMessagePanelFactory,
      AllFriendsRefreshManager allFriendsRefreshManager) {

    GuiUtils.assignResources(this);

    this.searchResultsModel = searchResultsModel;
    this.headerBarDecorator = headerBarDecorator;
    this.categoryIconManager = categoryIconManager;

    this.sponsoredResultsPanel = sponsoredResultsPanel;
    this.sponsoredResultsPanel.setVisible(false);
    this.browseFailedPanel = browseFailedMessagePanelFactory.create(searchResultsModel);

    // Create sort and filter components.
    sortAndFilterPanel = sortAndFilterFactory.create(searchResultsModel);

    filterPanel = filterPanelFactory.create(searchResultsModel, searchResultsModel.getSearchType());

    scrollPane = new JScrollPane();
    scrollPane.setBorder(BorderFactory.createEmptyBorder());
    scrollablePanel = new ScrollablePanel();
    configureEnclosingScrollPane();

    // Create results container with tables.
    resultsContainer = containerFactory.create(searchResultsModel);

    viewTypeListener =
        new SettingListener() {
          int oldSearchViewTypeId = SwingUiSettings.SEARCH_VIEW_TYPE_ID.getValue();

          @Override
          public void settingChanged(SettingEvent evt) {
            SwingUtilities.invokeLater(
                new Runnable() {
                  @Override
                  public void run() {
                    int newSearchViewTypeId = SwingUiSettings.SEARCH_VIEW_TYPE_ID.getValue();
                    if (newSearchViewTypeId != oldSearchViewTypeId) {
                      SearchViewType newSearchViewType = SearchViewType.forId(newSearchViewTypeId);
                      resultsContainer.setViewType(newSearchViewType);
                      syncScrollPieces();
                      oldSearchViewTypeId = newSearchViewTypeId;
                    }
                  }
                });
          }
        };
    SwingUiSettings.SEARCH_VIEW_TYPE_ID.addSettingListener(viewTypeListener);

    // Initialize header label.
    updateTitle();

    // Install listener to update header label.
    resultCountListener =
        new ListEventListener<VisualSearchResult>() {
          @Override
          public void listChanged(ListEvent<VisualSearchResult> listChanges) {
            updateTitle();
          }
        };
    searchResultsModel.getUnfilteredList().addListEventListener(resultCountListener);
    searchResultsModel.getFilteredList().addListEventListener(resultCountListener);

    // Configure sort panel and results container.
    sortAndFilterPanel.setSearchCategory(searchResultsModel.getSearchCategory());
    resultsContainer.showCategory(searchResultsModel.getSearchCategory());
    syncScrollPieces();

    // Configure advanced filters.
    filterPanel.setSearchCategory(searchResultsModel.getSearchCategory());
    filterPanel.addCategoryListener(
        new CategoryListener() {
          @Override
          public void categorySelected(SearchCategory displayCategory) {
            sortAndFilterPanel.setSearchCategory(displayCategory);
            resultsContainer.showCategory(displayCategory);
            syncScrollPieces();
            updateTitle();
          }
        });

    messageLabel = new JLabel();
    messagePanel = new JPanel();
    messagePanel.add(messageLabel);
    messagePanel.setVisible(false);

    browseStatusPanel = new BrowseStatusPanel(searchResultsModel, allFriendsRefreshManager);

    classicSearchReminderPanel = new ClassicSearchWarningPanel();
    layoutComponents();
  }