private void rememberScrollbarsOnMediators(String key) {
    AbstractLibraryTableMediator<?, ?, ?> tableMediator = null;
    AbstractLibraryListPanel listPanel = null;

    if (key.equals(FILES_TABLE_KEY)) {
      tableMediator = LibraryFilesTableMediator.instance();
      listPanel = getLibraryExplorer();
    } else if (key.equals(PLAYLISTS_TABLE_KEY)) {
      tableMediator = LibraryPlaylistsTableMediator.instance();
      listPanel = getLibraryPlaylists();
    } else if (key.equals(DEVICE_TABLE_KEY)) {
      tableMediator = LibraryDeviceTableMediator.instance();
      listPanel = getLibraryExplorer();
    }

    if (tableMediator == null || listPanel == null) {
      // nice antipattern here.
      return;
    }

    if (lastSelectedMediator != null && lastSelectedKey != null) {
      scrollbarValues.put(lastSelectedKey, lastSelectedMediator.getScrollbarValue());
    }

    lastSelectedMediator = tableMediator;
    lastSelectedKey = getSelectedKey();

    if (listPanel.getPendingRunnables().size() == 0) {
      int lastScrollValue =
          scrollbarValues.containsKey(lastSelectedKey) ? scrollbarValues.get(lastSelectedKey) : 0;

      tableMediator.scrollTo(lastScrollValue);
    }
  }
  /** Delete selected items from a playlist (not from disk) */
  public void removeSelection() {

    LibraryPlaylistsTableDataLine[] lines = getSelectedLibraryLines();

    if (currentPlaylist != null && currentPlaylist.getId() == LibraryDatabase.STARRED_PLAYLIST_ID) {
      for (LibraryPlaylistsTableDataLine line : lines) {
        PlaylistItem playlistItem = line.getInitializeObject();
        playlistItem.setStarred(false);
        playlistItem.save();
      }

      LibraryMediator.instance().getLibraryExplorer().refreshSelection();

    } else {

      for (LibraryPlaylistsTableDataLine line : lines) {
        PlaylistItem playlistItem = line.getInitializeObject();
        playlistItem.delete();
      }

      LibraryMediator.instance().getLibraryPlaylists().reselectPlaylist();

      clearSelection();
    }

    super.removeSelection();
  }
  /** Set up the constants */
  @SuppressWarnings("serial")
  protected void setupConstants() {
    super.setupConstants();
    MAIN_PANEL = new PaddedPanel();
    DATA_MODEL = new LibraryPlaylistsTableModel();
    DATA_MODEL.sort(LibraryPlaylistsTableDataLine.SORT_INDEX_IDX);

    TABLE =
        new LimeJTable(DATA_MODEL) {

          private Image bigAudioIcon = GUIMediator.getThemeImage("audio128x128").getImage();

          protected void paintComponent(java.awt.Graphics g) {
            // System.out.println("LibraryPlaylistTableMediator.getRowCount() " +
            // TABLE.getRowCount());
            if (TABLE.getRowCount() == 0) {
              drawHelpGraphics(g, bigAudioIcon);
            } else {
              super.paintComponent(g);
            }
          };
        };
    Action[] aa =
        new Action[] {
          LAUNCH_ACTION, OPEN_IN_FOLDER_ACTION, SEND_TO_FRIEND_ACTION, DELETE_ACTION, OPTIONS_ACTION
        };
    BUTTON_ROW = new ButtonRow(aa, ButtonRow.X_AXIS, ButtonRow.NO_GLUE);
  }
 @Override
 protected void setDefaultRenderers() {
   super.setDefaultRenderers();
   TABLE.setDefaultRenderer(PlayableIconCell.class, new PlayableIconCellRenderer());
   TABLE.setDefaultRenderer(PlayableCell.class, new PlayableCellRenderer());
   TABLE.setDefaultRenderer(PaymentOptions.class, new PaymentOptionsRenderer());
 }
 @Override
 protected void setDefaultRenderers() {
   super.setDefaultRenderers();
   TABLE.setDefaultRenderer(PlaylistItemBitRateProperty.class, new PlaylistItemPropertyRenderer());
   TABLE.setDefaultRenderer(PlaylistItemTrackProperty.class, new PlaylistItemPropertyRenderer());
   TABLE.setDefaultRenderer(PlaylistItemStringProperty.class, new PlaylistItemPropertyRenderer());
   TABLE.setDefaultRenderer(PlaylistItemStarProperty.class, new PlaylistItemStarRenderer());
   TABLE.setDefaultRenderer(LibraryNameHolder.class, new LibraryNameHolderRenderer());
 }
  /** Build some extra listeners */
  protected void buildListeners() {
    super.buildListeners();

    LAUNCH_ACTION = new LaunchAction();
    LAUNCH_OS_ACTION = new LaunchOSAction();
    OPEN_IN_FOLDER_ACTION = new OpenInFolderAction();
    CREATE_TORRENT_ACTION = new CreateTorrentAction();
    DELETE_ACTION = new RemoveFromPlaylistAction();
    SEND_TO_ITUNES_ACTION = new SendAudioFilesToiTunes();
  }
  @Override
  protected void addListeners() {
    super.addListeners();

    TABLE.addKeyListener(
        new KeyAdapter() {
          @Override
          public void keyReleased(KeyEvent e) {
            if (LibraryUtils.isRefreshKeyEvent(e)) {
              LibraryMediator.instance().getLibraryPlaylists().refreshSelection();
            }
          }
        });
  }
  /** Set up the constants */
  protected void setupConstants() {
    super.setupConstants();
    MAIN_PANEL = new PaddedPanel();
    DATA_MODEL = new LibraryFilesTableModel();

    // sort by modification time in descending order by default
    // so user can quickly find newest files.
    DATA_MODEL.sort(LibraryFilesTableDataLine.MODIFICATION_TIME_IDX);
    DATA_MODEL.sort(LibraryFilesTableDataLine.MODIFICATION_TIME_IDX);

    TABLE = new LimeJTable(DATA_MODEL);
    DATA_MODEL.setTable(TABLE);
    Action[] aa =
        new Action[] {
          LAUNCH_ACTION, OPEN_IN_FOLDER_ACTION, SEND_TO_FRIEND_ACTION, DELETE_ACTION, OPTIONS_ACTION
        };

    BUTTON_ROW = new ButtonRow(aa, ButtonRow.X_AXIS, ButtonRow.NO_GLUE);
  }
 @Override
 protected void sortAndMaintainSelection(int columnToSort) {
   super.sortAndMaintainSelection(columnToSort);
   resetAudioPlayerFileView();
 }
 public void playCurrentSelection() {
   if (currentMediator != null) {
     currentMediator.playCurrentSelection();
   }
 }
  /**
   * Override the default removal so we can actually stop sharing and delete the file. Deletes the
   * selected rows in the table. CAUTION: THIS WILL DELETE THE FILE FROM THE DISK.
   */
  public void removeSelection() {
    int[] rows = TABLE.getSelectedRows();
    if (rows.length == 0) return;

    if (TABLE.isEditing()) {
      TableCellEditor editor = TABLE.getCellEditor();
      editor.cancelCellEditing();
    }

    List<File> files = new ArrayList<File>(rows.length);

    // sort row indices and go backwards so list indices don't change when
    // removing the files from the model list
    Arrays.sort(rows);
    for (int i = rows.length - 1; i >= 0; i--) {
      File file = DATA_MODEL.getFile(rows[i]);
      files.add(file);
    }

    CheckBoxListPanel<File> listPanel =
        new CheckBoxListPanel<File>(files, new FileTextProvider(), true);
    listPanel.getList().setVisibleRowCount(4);

    // display list of files that should be deleted
    Object[] message =
        new Object[] {
          new MultiLineLabel(
              I18n.tr(
                  "Are you sure you want to delete the selected file(s), thus removing it from your computer?"),
              400),
          Box.createVerticalStrut(ButtonRow.BUTTON_SEP),
          listPanel,
          Box.createVerticalStrut(ButtonRow.BUTTON_SEP)
        };

    // get platform dependent options which are displayed as buttons in the dialog
    Object[] removeOptions = createRemoveOptions();

    int option =
        JOptionPane.showOptionDialog(
            MessageService.getParentComponent(),
            message,
            I18n.tr("Message"),
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE,
            null,
            removeOptions,
            removeOptions[0] /* default option */);

    if (option == removeOptions.length - 1 /* "cancel" option index */
        || option == JOptionPane.CLOSED_OPTION) {
      return;
    }

    // remove still selected files
    List<File> selected = listPanel.getSelectedElements();
    List<String> undeletedFileNames = new ArrayList<String>();

    boolean somethingWasRemoved = false;

    for (File file : selected) {
      // stop seeding if seeding
      BittorrentDownload dm = null;
      if ((dm = TorrentUtil.getDownloadManager(file)) != null) {
        dm.setDeleteDataWhenRemove(false);
        dm.setDeleteTorrentWhenRemove(false);
        BTDownloadMediator.instance().remove(dm);
      }

      // close media player if still playing
      if (MediaPlayer.instance().isThisBeingPlayed(file)) {
        MediaPlayer.instance().stop();
        MPlayerMediator.instance().showPlayerWindow(false);
      }

      // removeOptions > 2 => OS offers trash options
      boolean removed =
          FileUtils.delete(
              file, removeOptions.length > 2 && option == 0 /* "move to trash" option index */);
      if (removed) {
        somethingWasRemoved = true;
        DATA_MODEL.remove(DATA_MODEL.getRow(file));
      } else {
        undeletedFileNames.add(getCompleteFileName(file));
      }
    }

    clearSelection();

    if (somethingWasRemoved) {
      LibraryMediator.instance().getLibraryExplorer().refreshSelection(true);
    }

    if (undeletedFileNames.isEmpty()) {
      return;
    }

    // display list of files that could not be deleted
    message =
        new Object[] {
          new MultiLineLabel(
              I18n.tr(
                  "The following files could not be deleted. They may be in use by another application or are currently being downloaded to."),
              400),
          Box.createVerticalStrut(ButtonRow.BUTTON_SEP),
          new JScrollPane(createFileList(undeletedFileNames))
        };

    JOptionPane.showMessageDialog(
        MessageService.getParentComponent(), message, I18n.tr("Error"), JOptionPane.ERROR_MESSAGE);

    super.removeSelection();
  }