2017-07-18 6 views
1

異なるフォルダの場所にあるファイルを検索し、すべてのファイルをテーブルビューで表示するアプリケーションを開発しています。ユーザーが行をクリックすると、そのファイルがプログラムの右側に表示されます。現在、txt、mp3ファイル、mp4ファイルのために働いています。JavaFX mp3オーディオ、mp4オーディオ、テキストデータ重ねる

説明:
私は2つのサービス、FileSearchServiceFilePreviewServiceを作成しました。 FileSearchServiceは、ファイルを検索し、静的observableListにファイルを追加します。 FilePreviewServiceは選択された行を取得し、ファイルのタイプがtxtまたはmp3などであるかどうかをチェックし、FileProcessor抽象クラスを使用して選択したアイテムを処理します。選択されたアイテムのタイプがtxtの場合、FileProcessor、TextProcessorの子クラスが再生され、そのAnchorPaneに子としてTextAreaを含むAnchorPaneが返されます。テキストエリアは、選択した項目(行)から取得したテキストを設定します。最後に、anchorPaneがメインコントローラに返されます。メインコントローラーが項目を表示します。

問題:
私はMP4(またはmp3)を保持している行をクリックした場合、MP4(またはmp3を)ファイルのファイルは、罰金果たしていると私のanchorPaneに表示されます。 mp4(またはmp3)が再生されている間、txtファイルをクリックすると、そのファイルのデータがanchorPaneに表示されますが、mp4(またはmp3)のオーディオはまだ再生されています。

下記は私の問題を説明する2つの画像です。

ビデオファイルをクリックすると、アプリケーションの右側にビデオが表示されます。

enter image description here

は、今私はtxtファイルをクリックし、その後、anchorPaneは、テキストデータを示していますが、映像(むしろオーディオ)はまだ再生されています。

enter image description here

さて、私はmp3ファイルの両方mp3とのMP4オーディオのスーパーインポーズをクリックした場合。私は

は、私が唯一つの項目を実行取得したい欲しい

。 mp3ファイルが再生されている場合、mp4ビデオをクリックすると、mp3が停止し、ビデオが再生されます。私のアプリケーションは、複数の連続mp3またはmp4またはtxtのクリックを処理できます。 mp4ファイルをクリックしてからtxtファイルをクリックすると、処理されません。

FilePreviewService.Java

public class FilePreviewService extends Service<Void> { 
    FileModel model; 
    private FileProcesser fileProcesser; 
    String fileExtension = ""; 


    public FileProcesser getFileProcesser() { 
     return fileProcesser; 
    } 

    public FilePreviewService(FileModel model) { 
     this.model = model; 
     this.fileExtension = reverseFileName(getFileExtension(model)); 

    } 

    @Override 
    protected Task<Void> createTask() { 
     return new Task<Void>() { 
      @Override 
      protected Void call() throws Exception { 
       System.out.println("FIlePreviewService, createTask() Thread = " + Thread.currentThread().getName()); 
       fileProcesser = FileUtility.getFileProcesserFromUtil(fileExtension); 
       getFileProcesser().processFile(model.getFileLocation()); 
       return null; 
      } 


     }; 
    } 
} 

AudioProcesser.Java

public final class AudioProcesser extends FileProcesser{ 
    static AudioProcesser audioProcesser; 
    Media media; 
    MediaPlayer mediaPlayer; 


    public static AudioProcesser getAudioProcesser() { 
     if (audioProcesser == null) 
      audioProcesser = new AudioProcesser(); 
     return audioProcesser; 
    } 

    @Override 
    public void processFile(String fileLocation) throws Exception { 
     switch (getAudioMediaStatus()) { 
      case NOT_PLAYED: 
       playMedia(fileLocation); 
       break; 
      case PLAYING: 
       /* TIP: 
       If mediaPlayer.stop is placed after the line 
       * media = new Media(new File(fileLocation).toURI().toString()); 
        mediaPlayer = new MediaPlayer(media); 
        then multiple music play together when multiple different row gets selected, 
        one after another 
       */ 
       mediaPlayer.stop(); 
       playMedia(fileLocation); 
       break; 
      default: 
       System.out.println("Audio in default case"); 
     } 
    } 

    private void playMedia(String fileLocation) { 
     media = new Media(new File(fileLocation).toURI().toString()); 
     mediaPlayer = new MediaPlayer(media); 
     mediaPlayer.play(); 
     setAudioMediaStatus(PLAYING); 
    } 
} 

VideoProcesser.Java

public class VideoProcesser extends FileProcesser { 
    static VideoProcesser videoProcesser = null; 
    MediaPlayer mediaPlayer; 
    Media media; 
    MediaView mediaView; 

    @Override 
    public void processFile(String fileLocation) throws Exception { 
     switch (getVideoMediaStatus()) { 
      case NOT_PLAYED: 
       playVideo(fileLocation); 
       break; 
      case PLAYING: 
       mediaPlayer.stop(); 
       playVideo(fileLocation); 
       break; 
      default: 
       System.out.println("Audio in default case"); 
     } 


//  pane.getChildren().add(); 
    } 

    @Override 
    public AnchorPane getPane(){ 
     return pane; 
    } 


    private void playVideo(String fileLocation) { 
     System.out.println("VideoProcesser Thread = " + Thread.currentThread().getName()); 
     media = new Media(new File(fileLocation).toURI().toString()); 
     mediaPlayer = new MediaPlayer(media); 
//  mediaPlayer.setAutoPlay(true); 
     if(mediaView == null) { 
      mediaView = new MediaView(mediaPlayer); 
     } 
     mediaView.setMediaPlayer(mediaPlayer); 
     mediaView.setPreserveRatio(true); 
     mediaPlayer.play(); 
     mediaPlayer.setOnError(() -> System.out.println("Current error: "+mediaPlayer.getError())); 
     setVideoMediaStatus(PLAYING); 
     pane.getChildren().add(mediaView); 
    } 

    public static FileProcesser getVideoProcesser() { 
     if(videoProcesser == null) 
      videoProcesser = new VideoProcesser(); 
     return videoProcesser; 
    } 
} 

TextProcesser。Javaの

public class TextProcesser extends FileProcesser { 

    static TextProcesser textProcesser = null; 

    public static FileProcesser getTextProcesser() { 
     if(textProcesser == null) 
      textProcesser = new TextProcesser(); 
     return textProcesser; 
    } 

    @Override 
    public void processFile(String fileLocation) throws IOException { 
     InputStream inputStream = new FileInputStream(fileLocation); 
     Scanner sc = null; 

     //text file: 25.1_-_Marvel_Graph.txt, size 1.5MB 
     System.out.println("Data reading started = " + new Date()); 
     if (inputStream != null) { 
      StringBuilder txtData = new StringBuilder(""); 
      try { 
       sc = new Scanner(inputStream, "UTF-8"); 
       while (sc.hasNextLine()) { 
        txtData.append(sc.nextLine()); 
       } 
       // note that Scanner suppresses exceptions 
       if (sc.ioException() != null) { 
        throw sc.ioException(); 
       } 
      } finally { 
       if (inputStream != null) { 
        inputStream.close(); 
       } 
       if (sc != null) { 
        sc.close(); 
       } 
      } 
      dataToDisplay = txtData.toString(); 
     } 
     System.out.println("Data reading finished = " + new Date()); 

    } 

    @Override 
    public AnchorPane getPane(){ 
     TextArea txtArea = new TextArea(); 
     txtArea.setEditable(false); 
     txtArea.setText((String) dataToDisplay); 
     txtArea.setPrefHeight(778); 
     txtArea.setWrapText(true); 
     pane.getChildren().add(txtArea); 
     return pane; 
    } 
} 

MainController.Java

public void initialize(URL location, ResourceBundle resources) { 
     init(); 
     initFilePreviewExecutors(); 

     for (int i = 0; i < locationsToSearch.length; i++) { 
      fileModel = new FileModel(locationsToSearch[i]); 
      FileSearchService fileSearchService = new FileSearchService(fileModel); 
      fileSearchService.setExecutor(fileSearchExecutor); 
      fileSearchService.setOnSucceeded(e -> { 
       fileSearchService.setFileSearchCompleted(true); 
       searchFinished = true; 
      }); 
      fileSearchService.start(); 

      CacheFileService cfs = new CacheFileService(locationsToSearch[i]); 

     } 
     try { 
      stop(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     nameCol.setCellValueFactory(new PropertyValueFactory<>("fileName")); 
     sizeCol.setCellValueFactory(new PropertyValueFactory<>("fileSize")); 
     locationCol.setCellValueFactory(new PropertyValueFactory<>("fileLocation")); 

     recordsTableView.setItems(fileModel.getData()); 

     recordsTableView.setContextMenu(new ContextMenu(showRecordInfo)); 

     recordsTableView.setRowFactory(tv -> { 
      TableRow<FileModel> row = new TableRow<>(); 
      row.setOnMouseClicked(event -> { 
       if(!row.isEmpty() && event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 1) { 
        FileModel fileModel = row.getItem(); 
        filePreviewService = new FilePreviewService(fileModel); 
        filePreviewService.setExecutor(filePreviewExecutor); 
        filePreviewService.setOnSucceeded(event1 -> { 
         recordPreviewPane = filePreviewService.getFileProcesser().getPane(); 
         if(recordPreviewPane == null) { 
          System.out.println("RECORDPREVIEWPANE IS NULL"); 
         } 
         previewPane.setContent(recordPreviewPane); 
        }); 
        filePreviewService.restart(); 

       } else if(!row.isEmpty() && event.getButton() == MouseButton.SECONDARY) { 
        FileModel fileModel = row.getItem(); 
         showRecordInfo.setOnAction(e -> { 
         Scene scene = defaultViewFactory.getRecordInfoScene(fileModel); 
         Stage stage = new Stage(); 
         stage.setScene(scene); 
         stage.show(); 
        }); 

       } 
      }); 
      return row;}); 


    } 

私は私が私の質問を明らかにしたいと考えています。あなたが他のjavaファイルを見たい場合、以下はプロジェクトへのリンクです。 Github :

編集:私の問題を解決する方法は非常に非効率的です。 FilePreviewServiceにコードを追加しました。もちろん、以下のコードはさらにいくつかの条件を満たす必要があります。それは非常に非効率的なアプローチです。

getFileProcesser().processFile(model.getFileLocation()); 
       if(i > 0) { 
        oldFileProcesser = fileProcesserStack.pop(); 
       } 
       if(fileProcesser != null) { 
        fileProcesserStack.push(fileProcesser); 
       } 

       //audio and video consecutive play fixing 

       if(i > 0 && (oldFileProcesser instanceof AudioProcesser || oldFileProcesser instanceof VideoProcesser) 
         && !(fileProcesser instanceof AudioProcesser || fileProcesser instanceof VideoProcesser)) { 
        if(oldFileProcesser instanceof AudioProcesser) { 
         AudioMediaStatus.setAudioMediaStatus(AudioMediaStatus.JUST_STOP); } 
        if(oldFileProcesser instanceof VideoProcesser) { 
         VideoMediaStatus.setVideoMediaStatus(VideoMediaStatus.JUST_STOP);} 
        oldFileProcesser.processFile(""); 
       } 
       i++; 

答えて

1

私が正しく理解していれば、.mp4が再生されるときに.mp3を停止しようとしているか、その逆の場合もあります。

まず、あなたの問題の理由。 .mp3を起動すると、AudioProcesserが呼び出されます。したがって、そのクラスを通して新しいMediaPlayerを開始します。 しかし、あなたはVideoProcesserクラスを使って同じことをします。だから、今は2つのMediaPlayerが同時に動いているのですが、それがオーディオのオーバーレイの理由です。

解決策は、インスタンス変数を持ち、他のクラスが呼び出すいくつかの新しいメソッド、つまりstopMediaPlayer()メソッドを公開します。

可能な限りあなたのコードを、わずかの変更で、以下の実施例、:

public final class AudioProcesser extends FileProcesser{ 
    //Always have one instance of the variable. 
    static AudioProcesser audioProcesser = new AudioProcesser(); 
    private Media media; 
    private MediaPlayer mediaPlayer; 

    public static AudioProcesser getAudioProcesser() { 
     return audioProcesser; 
    } 

    //Added an exposure to the underlying audioMediaStatus 
    public void setAudioMediaStatus(AudioMediaStatus status){ 
     AudioMediaStatus.setAudioMediaStatus(status); 
    } 
    //Another exposure to the underlying audioMediaStatus 
    public AudioMediaStatus getAudioMediaStatus(){ 
     return AudioMediaStatus.getAudioMediaStatus(); 
    } 
    //Used only for this class 
    private void setMediaPlayer(String fileLocation){ 
     Media media = new Media(new File(fileLocation).toURI().toString()); 
     mediaPlayer = new MediaPlayer(media); 
    } 

    //Exposed a stop method. 
    public void stopMedia(){ 
     if(mediaPlayer != null) { 
      //Change this accordingly. 
      setAudioMediaStatus(AudioMediaStatus.NOT_PLAYED); 
      mediaPlayer.stop(); 
     } 
    } 

    @Override 
    public void processFile(String fileLocation) throws Exception { 
     switch (getAudioMediaStatus()) { 
      case NOT_PLAYED: 
       playMedia(fileLocation); 
       break; 
      case PLAYING: 
       /* TIP: 
       If mediaPlayer.stop is placed after the line 
       * media = new Media(new File(fileLocation).toURI().toString()); 
        mediaPlayer = new MediaPlayer(media); 
        then multiple music play together when multiple different row gets selected, 
        one after another 
       */ 
       mediaPlayer.stop(); 
       playMedia(fileLocation); 
       break; 
      default: 
       System.out.println("Audio in default case"); 
     } 
    } 

    private void playMedia(String fileLocation) { 

     VideoProcesser.getVideoProcesser().stopMedia(); 
     //Moved the previous statements to its own method. 
     setMediaPlayer(fileLocation); 
     mediaPlayer.play(); 
     setAudioMediaStatus(AudioMediaStatus.PLAYING); 
    } 
} 

あなたが見ることができるように、私はいくつかの項目、すなわち、いくつかのメソッドを追加しましたし、私はあなたの静的な輸入品を処分しました。注目すべき重要な点は、stopMedia()メソッドとplayMedia()メソッドの最初の行です。

stopMediaメソッドは、名前のとおりです。 playMediaメソッドでは、VideoProcesser.getVideoProcesser().stopMedia()を最初の行として追加したことがわかります。

クラスはほぼ同じですので、追加されたメソッドとマイナーな調整が転送されます。私はこれをテストして動作します。

txtファイルを選択したときにオーディオ/ビデオを停止したいので、同じクラスのビデオとオーディオの同じ呼び出しをstopMediaメソッドに追加する必要があります。

+0

ええ、私はそれを理解しています。後で、ビデオファイルの一部を録音するなど、VideoProcesserにさらに機能を追加します。オーディオとビデオプロセッサーを一緒にマージしても、もう1つの問題が残っています。オーディオが再生されている間に、テキストファイルをクリックすると、オーディオが再生され続けます。 私はこの問題を解決する方法は非常に非効率的です、私は質問を更新しました。私は実際にファイルプロセッサを使用して、それをスタックに置いて、前のファイルプロセッサがAudioProcessor型であるかどうかをチェックしてから、それぞれのprocessFile()メソッドを呼び出して停止します。 – karna

+0

ああ、私は参照してください。私はあなたのコードとリファクタリングを試みましたが、私の考えにはあまりにも多くの変更が必要です。たぶん誰か他の人がアイデアを持っています –

+0

私にあなたのアイデアを教えてください。 – karna

関連する問題