- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个应用程序,该应用程序可以查找不同文件夹位置中的文件并在表格 View 中显示所有文件。如果用户单击一行,则该文件将显示在程序的右侧。目前,它适用于 txt、mp3 文件和 mp4 文件。
描述:
我创建了两个服务:FileSearchService 和 FilePreviewService。 FileSearchService 搜索文件并将其添加到静态 observableList 中。 FilePreviewService 获取所选行,检查文件类型是否为 txt、mp3 或其他类型,并使用 FileProcessor 抽象类来处理所选项目。如果所选项目的类型为 txt,则 FileProcessor 的子类 TextProcessor 发挥作用并返回一个 AnchorPane,其中 TextArea 作为附加到该 AnchorPane 的子类。文本区域设置从所选项目(行)获取的文本。最后anchorPane返回到主 Controller 。主 Controller 然后显示该项目。
问题:
如果我单击包含 mp4(或 mp3)文件的行,则 mp4(或 mp3)文件可以正常播放并显示在我的 anchor Pane 上。当 mp4(或 mp3)正在播放时,如果我点击一个 txt 文件,那么该文件的数据将显示在anchorPane上,但 mp4(或 mp3)的音频仍在播放。
下面是描述我的问题的两张图片。
我点击了一个视频文件,视频显示在我的应用程序的右侧。
现在我点击一个txt文件,然后anchorPane显示textData,但视频(而不是音频)仍在播放。
现在,如果我单击 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++;
最佳答案
如果我理解正确,您正在尝试在播放 .mp4 时停止 .mp3,反之亦然。
首先是你的问题的原因。当您启动 .mp3 时,您正在调用 AudioProcesser
,很酷,很棒。因此,您通过该类启动一个新的MediaPlayer
。但是,您可以使用 VideoProcesser 类执行相同的操作。现在您有两个 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()
作为第一行。
Audio/VideoProcesser
类几乎相同,因此添加的方法和细微的调整将转移,我已经测试过它并且它确实有效。
由于您还想在选择 txt
文件时停止音频/视频,因此您需要在该类中添加对视频和音频 stopMedia
方法的相同调用也是如此。
关于JavaFX mp3音频、mp4音频、文本数据叠加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45162770/
我不知道这是不是问这种问题的最佳地点, 我看到一些 JavaFX伙计们,重新标记 一些问题通过替换 javafx来自 javafx-2并采用新的 javafx-8 .它被弃用了还是什么? 编辑 : 不
错误本身: Error:java: invalid flag: --add-modules=javafx.fxml,javafx.graphics,javafx.controls,javafx.bas
这个想法是让一个应用程序在每个显示器上显示两个不同的窗口(阶段),该应用程序应该知道计算机有多少个显示器及其分辨率。 javafx有可能吗? 最佳答案 对于当前版本的 JavaFX (2.2),您可以
我正在将我的项目从 javafx 1.3 转换为 javafx 2.1。但我对 javafx.lang 有疑问包裹。 最佳答案 JavaFX 1.3 lang 包内容被拆分并移至下一个位置: 时长变为
当我尝试将标签添加到 gridpane 中时,如第二张图片所示,它不起作用。我已经尝试了很多东西,比如添加 CSS,但它仍然无法正常工作。为什么第 113 和 114 行不起作用? (opcje.se
我有一个JavaFX ContextMenu分配给滚动面板的鼠标右键单击。它会打开,但在滚动 Pane 外部单击时不会关闭。我可以在滚动 Pane 中添加另一个鼠标事件以将其隐藏,但这只能解决1个问题
我有一个tableview,其中附有一个可观察到的自定义类对象的列表(类类型:SalesInvoiceNetSale)。该表中的所有数据都可以正常显示。可观察列表中的最后一项是总计行(类类型:Sale
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 2年前关闭。 Improve this questi
我想知道如何在JavaFX中绘制半圆。我尝试使用Shape和QuadCurve,但无法制作出完美的半圆。 这是我要绘制的图片: 最佳答案 您链接的图片实际上是一个半圆环。您可以通过绘制嵌套的2条圆弧和
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在寻找 JavaFX 支持的图像类型(最新)列表,例如PNG、JPEG、TIFF。不同的搜索引擎没有帮助......知道从哪里开始吗? 更特别的是,我对 16 位灰度图像(不同格式)和罕见的受支持
我希望在 javafx 中让标签每 0.1 秒闪烁一次。文本显示在后台运行的 ImageView gif 的顶部。我将如何去做,或者您对最佳方法有什么建议? 谢谢 最佳答案 @fabian 的解决方案
我需要测试所选项目的值以调用不同的方法,因此我编写了添加侦听器的代码,但是该代码生成语法错误 @FXML private JFXComboBox cmbComp; cmbComp.valuePrope
我正在 Javafx 中编写一个非常简单的应用程序,其中舞台上有一个带有文本框的按钮作为一个场景。现在,我想要的行为是,当我单击按钮时,我可以使用另一个按钮加载另一个场景和舞台上的一个文本框,然后删除
编辑:如果用户单击“删除”以删除 ListView 中的项目,我会弹出一个警告框。它有效,但我希望它能超越原来的舞台。它出现在我的第一台显示器上。有什么方法可以设置警报显示时的位置吗? 请注意,“所有
我想使用 JavaFX 编写一个笔画绘图应用程序。我有一个压敏绘图板,如果能够读取笔的压力和倾斜值,那就太好了。 JavaFX 有一个 API 可以处理鼠标、触摸和滑动输入,但似乎没有任何东西可以产生
我在 JavaFX 中使用条形图和折线图。当我使两个图表大小相同并将它们放在同一位置时,它们完美地相互重叠。我如何使折线图显示在条形图的顶部。 目前我已将它们的不透明度设置为 0.7,这样它们“看起来
此问题与 this 相关。现在我想为字段值等于某个值的行着色。 @FXML private TableView tv_mm_view; @FXML private Ta
我有一个程序,可以生成高度图(0-255 的整数的 2D 数组),并使用 Shape3D“Box”对象为每个“像素”构建 3D View ,其高度与其在高度图中的值成比例。这会创建一个看起来很酷的四四
我想为 JavaFX 创建上下文菜单。这是我测试过的代码。但是由于某种原因,当我右键单击树节点时没有上下文菜单。你能帮我找出我的错误吗。 import java.util.Arrays; import
我是一名优秀的程序员,十分优秀!