예제 #1
1
 @FXML
 void loadSelectedPlaylist() {
   Playlist p = (Playlist) playlistsView.getSelectionModel().getSelectedItem();
   if (p == null) return;
   tracksView.setPlaceholder(offlinePlaceHolder);
   Platform.runLater(
       () -> {
         List<Track> tracks = p.getTracks();
         tracksView.getItems().clear();
         for (int i = tracks.size() - 1; i >= 0; i--) {
           tracksView.getItems().add(tracks.get(i));
         }
         if (findTrack) {
           Platform.runLater(
               () -> {
                 tracksView.getSelectionModel().select(currentTrack);
                 tracksView.scrollTo(currentTrack);
                 tracksView.requestFocus();
                 findTrack = false;
               });
         } else {
           if (tracksView.getItems().size() > 0) {
             tracksView.scrollTo(0);
           }
         }
       });
 }
예제 #2
0
 void playRandom() {
   List<Track> tracks = tracksView.getItems();
   Random random = new Random();
   int size = tracks.size();
   int r = random.nextInt(size - 1);
   tracksView.getSelectionModel().select(r);
   tracksView.scrollTo(tracksView.getSelectionModel().getSelectedIndex());
   Track nextTrack = (Track) tracksView.getSelectionModel().getSelectedItem();
   playTrack(nextTrack);
 }
예제 #3
0
 void playPrevious() {
   if (playStack.size() < 2) return;
   System.out.println("------------");
   for (PlaylistAndTrack pnt : playStack) {
     System.out.println(pnt.track.getTitle());
   }
   playStack.removeFirst();
   PlaylistAndTrack prevPlaylistAndTrack = playStack.removeFirst();
   playlistsView.getSelectionModel().select(prevPlaylistAndTrack.playlist);
   tracksView.getSelectionModel().select(prevPlaylistAndTrack.track);
   tracksView.scrollTo(tracksView.getSelectionModel().getSelectedIndex());
   playTrack(prevPlaylistAndTrack.track);
 }
예제 #4
0
 private void hideTablesHeaders() {
   List<Pane> headers =
       Arrays.asList(
           (Pane) tracksView.lookup("TableHeaderRow"),
           (Pane) playlistsView.lookup("TableHeaderRow"));
   headers.forEach(
       header -> {
         header.setMaxHeight(0);
         header.setMinHeight(0);
         header.setPrefHeight(0);
         header.setVisible(false);
       });
 }
예제 #5
0
 void addToPlaylist(List<File> files, Playlist p) {
   if (interfaceDisabled) return;
   new Thread(
           () -> {
             setInterfaceDisabled(true);
             int total = files.size();
             AtomicInteger current = new AtomicInteger(0);
             Cache.pushToPlaylist(
                 files,
                 p,
                 (Track t) -> {
                   Platform.runLater(
                       () -> {
                         infoLabel.setText(
                             String.format(
                                 res.getString("processed"),
                                 current.incrementAndGet(),
                                 total,
                                 t.getTitle()));
                         if (p == getSelectedPlaylist()) {
                           tracksView.getItems().remove(t);
                           tracksView.getItems().add(0, t);
                         }
                       });
                 });
             setInterfaceDisabled(false);
           })
       .start();
   if (p == getSelectedPlaylist()) {
     Platform.runLater(
         () -> {
           loadSelectedPlaylist();
         });
   }
 }
예제 #6
0
  private void setupTracksView() {
    TableColumn titleColumn = new TableColumn("Title");
    titleColumn.setSortable(false);
    titleColumn.setMinWidth(USE_COMPUTED_SIZE);
    titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));

    TableColumn durationColumn = new TableColumn("Duration");
    durationColumn.setMinWidth(60);
    durationColumn.setMaxWidth(60);
    durationColumn.setSortable(false);
    durationColumn.setCellValueFactory(new PropertyValueFactory<>("durationFormatted"));
    durationColumn.getStyleClass().add("text-layout-center");

    tracksView.getColumns().clear();
    tracksView.getColumns().addAll(titleColumn, durationColumn);
    tracksView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
  }
예제 #7
0
 void menuAddToPlaylist() {
   Track t = getSelectedTrack();
   if (t == null) {
     return;
   }
   ChoiceDialog<Playlist> dialog = playlistSelectionDialog(playlistsView.getItems());
   Optional<Playlist> result = dialog.showAndWait();
   result.ifPresent(playlist -> addToPlaylist(t, playlist));
 }
예제 #8
0
 @FXML
 void search() {
   searching = true;
   new Thread(
           () -> {
             List<Track> tracks = Cache.search(searchText.getText());
             tracksView.setPlaceholder(searchPlaceholder);
             Platform.runLater(
                 () -> {
                   if (tracksView.getItems().size() > 0) {
                     tracksView.scrollTo(0);
                   }
                   tracksView.getItems().clear();
                   tracksView.getItems().addAll(tracks.toArray());
                 });
           })
       .start();
 }
예제 #9
0
 private void setInterfaceDisabled(boolean disabled) {
   playlistsView.setDisable(disabled);
   searchButton.setDisable(disabled);
   searchText.setDisable(disabled);
   addButton.setDisable(disabled);
   renameButton.setDisable(disabled);
   deleteButton.setDisable(disabled);
   refreshButton.setDisable(disabled);
   interfaceDisabled = disabled;
 }
예제 #10
0
  private void setupPlaylistsView() {
    TableColumn titleColumn = new TableColumn("Title");
    titleColumn.setMinWidth(USE_COMPUTED_SIZE);
    titleColumn.setSortable(false);
    titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));

    TableColumn countColumn = new TableColumn("Tracks");
    countColumn.setMinWidth(60);
    countColumn.setMaxWidth(60);
    countColumn.setSortable(false);
    countColumn.setCellValueFactory(new PropertyValueFactory<>("count"));
    countColumn.getStyleClass().add("text-layout-right");

    playlistsView.getColumns().clear();
    playlistsView.getColumns().addAll(titleColumn, countColumn);
    playlistsView.setContextMenu(playlistsContextMenu);
    playlistsView.setPlaceholder(playlistPlaceholder);
    playlistsView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
  }
예제 #11
0
 void createOfflinePlaylist() {
   if (interfaceDisabled) return;
   TextInputDialog dialog = new TextInputDialog(res.getString("new_offline_playlist"));
   dialog.setTitle(res.getString("create_new_offline_playlist"));
   dialog.setHeaderText(res.getString("create_new_playlist"));
   dialog.setContentText(res.getString("enter_playlist_name"));
   dialog.getDialogPane().getStylesheets().add("/styles/dialogs.css");
   ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().addAll(logoImages);
   Optional<String> result = dialog.showAndWait();
   result.ifPresent(
       title -> {
         Platform.runLater(
             () -> {
               Playlist newPlaylist = Cache.createPlaylist(title);
               Platform.runLater(
                   () -> {
                     playlistsView.getItems().add(newPlaylist);
                     playlistsView.getSelectionModel().select(newPlaylist);
                   });
             });
       });
 }
예제 #12
0
 void updatePlaylists() {
   if (interfaceDisabled) return;
   final ObservableList<Playlist> items = playlistsView.getItems();
   items.clear();
   items.addAll(Cache.playlists());
   if (Settings.rememberedPlaylistId != null)
     for (Playlist p : items) {
       if (p.getId().equals(Settings.rememberedPlaylistId)) {
         rememberedPlaylist = p;
         break;
       }
     }
 }
예제 #13
0
 void playNext() {
   List<Track> tracks = tracksView.getItems();
   int selected = tracksView.getSelectionModel().getSelectedIndex();
   int next = selected + 1;
   if (next >= tracks.size()) {
     next = 0;
   }
   tracksView.getSelectionModel().select(next);
   tracksView.scrollTo(tracksView.getSelectionModel().getSelectedIndex());
   Track nextTrack = (Track) tracksView.getSelectionModel().getSelectedItem();
   playTrack(nextTrack);
 }
예제 #14
0
 void findPlayingTrack() {
   if (currentPlaylist == playlistsView.getSelectionModel().getSelectedItem()) {
     tracksView.getSelectionModel().select(currentTrack);
     tracksView.scrollTo(currentTrack);
     tracksView.requestFocus();
   } else {
     findTrack = true;
     Platform.runLater(
         () -> {
           playlistsView.getSelectionModel().select(currentPlaylist);
           playlistsView.scrollTo(currentPlaylist);
         });
   }
 }
예제 #15
0
 void setupPlaylistsContextMenu() {
   ContextMenu cm = playlistsContextMenu;
   MenuItem createOffline =
       menuItem(
           res.getString("create_offline_playlist"),
           () -> {
             createOfflinePlaylist();
           });
   MenuItem setAsFeatured =
       menuItem(
           res.getString("set_as_featured"),
           () -> {
             Playlist selectedPlaylist =
                 (Playlist) playlistsView.getSelectionModel().getSelectedItem();
             if (selectedPlaylist != null) {
               rememberedPlaylist = selectedPlaylist;
               Settings.rememberedPlaylistId = selectedPlaylist.getId();
               infoLabel.setText(
                   String.format(res.getString("featured_set"), selectedPlaylist.getTitle()));
             }
           });
   MenuItem rename =
       menuItem(
           "(...) " + res.getString("rename_playlist"),
           () -> {
             renamePlaylist();
           });
   MenuItem delete =
       menuItem(
           "(-) " + res.getString("delete_playlist"),
           () -> {
             deletePlaylist();
           });
   cm.getItems()
       .addAll(
           createOffline,
           new SeparatorMenuItem(),
           setAsFeatured,
           new SeparatorMenuItem(),
           rename,
           delete);
 }
예제 #16
0
  @FXML
  void refreshPlaylists() {
    infoLabel.setText(res.getString("refreshing"));
    log.info("Refreshing playlists");

    ObservableList<Playlist> items = playlistsView.getItems();
    items.clear();
    items.addAll(Cache.playlists());

    if (Settings.rememberedPlaylistId != null)
      for (Playlist p : items) {
        if (p.getId().equals(Settings.rememberedPlaylistId)) {
          rememberedPlaylist = p;
          break;
        }
      }

    infoLabel.setText(res.getString("playlists_refreshed"));
    log.info("Playlists refreshed");
  }
예제 #17
0
 void setupShortcuts() {
   Platform.runLater(
       () -> {
         stateButton
             .getScene()
             .getAccelerators()
             .put(
                 new KeyCodeCombination(KeyCode.F3),
                 (Runnable)
                     () -> {
                       if (!interfaceDisabled) SwingAppenderUI.getInstance().show();
                     });
         stateButton
             .getScene()
             .getAccelerators()
             .put(
                 new KeyCodeCombination(KeyCode.F),
                 (Runnable)
                     () -> {
                       if (!interfaceDisabled) findPlayingTrack();
                     });
         stateButton
             .getScene()
             .getAccelerators()
             .put(
                 new KeyCodeCombination(KeyCode.F5),
                 (Runnable)
                     () -> {
                       if (!interfaceDisabled) Platform.runLater(() -> refreshPlaylists());
                     });
         stateButton
             .getScene()
             .getAccelerators()
             .put(
                 new KeyCodeCombination(KeyCode.F4),
                 (Runnable)
                     () -> {
                       if (numpadOff) {
                         setupGlobalKeys();
                         Platform.runLater(
                             () -> {
                               infoLabel.setText(res.getString("global_hotkeys_on"));
                               log.info("Global hotkeys ON");
                             });
                       } else {
                         hotkeysProvider.reset();
                         Platform.runLater(
                             () -> {
                               infoLabel.setText(res.getString("global_hotkeys_off"));
                               log.info("Global hotkeys OFF");
                             });
                       }
                       numpadOff = !numpadOff;
                     });
         tracksView.setOnKeyPressed(
             (evt) -> {
               if (interfaceDisabled) return;
               if (evt.getCode().equals(KeyCode.DELETE)) {
                 deleteTrackFromPlaylist();
                 evt.consume();
               } else if (evt.getCode().equals(KeyCode.ENTER)) {
                 playSelectedTrack();
                 evt.consume();
               } else if (evt.getCode().equals(KeyCode.F2)) {
                 renameTrack();
                 evt.consume();
               }
             });
         playlistsView.setOnKeyPressed(
             (evt) -> {
               if (interfaceDisabled) return;
               if (evt.getCode().equals(KeyCode.F2)) {
                 renamePlaylist();
                 evt.consume();
               }
             });
       });
   setupGlobalKeys();
 }
예제 #18
0
  @Override
  public void initialize(URL location, ResourceBundle resources) {
    AppController.instance = this;
    this.res = resources;

    ObservableList<String> modeItems =
        FXCollections.observableArrayList(
            Settings.MODE_NEXT, Settings.MODE_RANDOM, Settings.MODE_SAME);
    modeList.setItems(modeItems);
    modeList.getSelectionModel().select(Settings.currentMode);
    modeList
        .valueProperty()
        .addListener(
            (ObservableValue ov, Object oldVal, Object newVal) -> {
              Settings.currentMode = (String) newVal;
            });

    setupPlaylistsView();
    setupPlaylistsContextMenu();

    setupTracksView();

    tracksView.setContextMenu(tracksContextMenu);
    tracksView.setOnContextMenuRequested(
        (ContextMenuEvent evt) -> {
          setupTracksContextMenu();
          evt.consume();
        });
    tracksView
        .getSelectionModel()
        .selectedItemProperty()
        .addListener(
            (ObservableValue observable, Object oldValue, Object newValue) -> {
              Settings.lastTrackId = newValue != null ? ((Track) newValue).getId() : null;
            });

    playlistsView
        .getSelectionModel()
        .selectedItemProperty()
        .addListener(
            (ObservableValue observable, Object oldValue, Object newValue) -> {
              loadSelectedPlaylist();
              Settings.lastPlaylistId = newValue != null ? ((Playlist) newValue).getId() : null;
              searching = false;
              searchText.setText(StringUtils.EMPTY);
            });

    volumeSlider.setCursor(Cursor.HAND);
    volumeSlider
        .valueProperty()
        .addListener(
            (ObservableValue<? extends Number> ov, Number oldVal, Number newVal) -> {
              if (player != null) {
                player.setVolume(newVal.doubleValue());
              }
              Settings.currentVolume = newVal.doubleValue();
              volumeLabel.setText(
                  String.valueOf((int) Math.ceil(newVal.doubleValue() * 100)) + "%");
            });
    volumeSlider.setValue(Settings.currentVolume);

    imagePlay = new ImageView(new Image(getClass().getResourceAsStream("/images/button_play.png")));
    imagePlay.setScaleX(0.40);
    imagePlay.setScaleY(0.40);
    imagePause =
        new ImageView(new Image(getClass().getResourceAsStream("/images/button_pause.png")));
    imagePause.setScaleX(0.5);
    imagePause.setScaleY(0.5);
    imageSettings =
        new ImageView(new Image(getClass().getResourceAsStream("/images/settings.png")));
    imageSettings.setScaleX(0.5);
    imageSettings.setScaleY(0.5);
    imageUpdate = new ImageView(new Image(getClass().getResourceAsStream("/images/refresh.png")));
    imageUpdate.setScaleX(0.5);
    imageUpdate.setScaleY(0.5);
    imageAdd = new ImageView(new Image(getClass().getResourceAsStream("/images/add.png")));
    imageAdd.setScaleX(0.5);
    imageAdd.setScaleY(0.5);
    imageRename = new ImageView(new Image(getClass().getResourceAsStream("/images/rename.png")));
    imageRename.setScaleX(0.5);
    imageRename.setScaleY(0.5);
    imageDelete = new ImageView(new Image(getClass().getResourceAsStream("/images/delete.png")));
    imageDelete.setScaleX(0.5);
    imageDelete.setScaleY(0.5);

    stateButton.setGraphic(imagePlay);
    settingsButton.setGraphic(imageSettings);
    refreshButton.setGraphic(imageUpdate);
    refreshButton.setTooltip(new Tooltip(res.getString("tooltip_sync")));

    addButton.setGraphic(imageAdd);
    addButton.setOnAction((evt) -> createOfflinePlaylist());
    addButton.setTooltip(new Tooltip(res.getString("tooltip_add_offline")));
    renameButton.setGraphic(imageRename);
    renameButton.setOnAction(evt -> renamePlaylist());
    renameButton.setTooltip(new Tooltip(res.getString("rename_playlist")));
    deleteButton.setGraphic(imageDelete);
    deleteButton.setOnAction(evt -> deletePlaylist());
    deleteButton.setTooltip(new Tooltip(res.getString("delete_playlist")));

    loadProgressBar.setCursor(Cursor.HAND);
    volumeSlider.setCursor(Cursor.HAND);
    updatePlaylists();
    if (Settings.lastPlaylistId != null) {
      currentPlaylist =
          ((ObservableList<Playlist>) playlistsView.getItems())
              .stream()
              .filter((playlist) -> playlist.getId().equals(Settings.lastPlaylistId))
              .findFirst()
              .orElse(null);
      playlistsView.getSelectionModel().select(currentPlaylist);
      playlistsView.scrollTo(currentPlaylist);
      Platform.runLater(
          () -> {
            if (Settings.lastTrackId != null) {
              currentTrack =
                  ((ObservableList<Track>) tracksView.getItems())
                      .stream()
                      .filter((track) -> track.getId().equals(Settings.lastTrackId))
                      .findFirst()
                      .orElse(null);
              tracksView.getSelectionModel().select(currentTrack);
              tracksView.scrollTo(currentTrack);
            }
          });
    }
    new Timer()
        .scheduleAtFixedRate(
            new TimerTask() {
              @Override
              public void run() {
                updatePlayProgress();
              }
            },
            100,
            100);
    setupTracksContextMenu();

    setupShortcuts();

    Platform.runLater(
        () -> {
          tracksView.requestFocus();
        });
  }
예제 #19
0
 Playlist getSelectedPlaylist() {
   if (searching) return null;
   return (Playlist) playlistsView.getSelectionModel().getSelectedItem();
 }
예제 #20
0
 void fillTracks(List<Track> tracks) {
   ObservableList<Track> items = FXCollections.observableArrayList(tracks);
   tracksView.setItems(items);
 }
예제 #21
0
 Track getSelectedTrack() {
   return (Track) tracksView.getSelectionModel().getSelectedItem();
 }
예제 #22
0
 void playSelectedTrack() {
   Track t = (Track) tracksView.getSelectionModel().getSelectedItem();
   if (t != null) Settings.lastTrackId = t.getId();
   playTrack(t);
 }
예제 #23
0
  @FXML
  void playTrack(Track t) {
    if (tweenBlock) return;
    tweenBlock = true;
    stop(
        () -> {
          currentPlaylist = (Playlist) playlistsView.getSelectionModel().getSelectedItem();
          currentTrack = t;
          if (player != null) {
            player.dispose();
          }
          if (t == null) {
            return;
          }
          timeUpdate = 9;
          if (currentPlaylist != null) {
            Tray.announce("[" + currentPlaylist.getTitle() + "] " + t.getTitle());
          }

          Platform.runLater(
              () -> {
                infoLabel.setText(res.getString("playing_offline") + t.getTitle());
                log.info("Playing offline: " + t.getTitle());
              });
          try {
            Media media = new Media(Cache.getContent(t).toURI().toString());
            player = new MediaPlayer(media);
            player.setVolume(Settings.currentVolume);
            player.play();
          } catch (MediaException ex) {
            Platform.runLater(
                () -> {
                  infoLabel.setText(
                      String.format(res.getString("cant_play_offline_not_exist"), t.getTitle()));
                  log.error("Can't play: seems that track does not exist - " + t.getTitle());
                });
          }

          if (player != null) {
            pushToPlayStack(getSelectedPlaylist(), t);
            player.setOnEndOfMedia(
                () -> {
                  String mode = Settings.currentMode;
                  if (mode.equals(Settings.MODE_NEXT)) {
                    playNext();
                  } else if (mode.equals(Settings.MODE_RANDOM)) {
                    playRandom();
                  } else if (mode.equals(Settings.MODE_SAME)) {
                    playSame();
                  }
                });
          }

          Platform.runLater(
              () -> {
                isPlaying = true;
                tweenBlock = false;
                titleLabel.setText(t.getTitle());
                stateButton.setGraphic(imagePause);
              });
        });
  }
예제 #24
0
 void deleteFromOfflinePlaylist(Track t, Playlist p) {
   if (interfaceDisabled) return;
   tracksView.getItems().remove(t);
   Cache.deleteFromPlaylist(t, p);
 }