我正试图在窗口的右上角显示通知,我正在播放动画和声音。当我第一次启动Test.main()时,下面的代码工作得很好,但是当我试图播放相同的动画和声音时,它不工作。请帮帮我。thanks in advance
Test.java
public class Test {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
executor.scheduleAtFixedRate(new NotificationRunnable(), 0, 2 * 60, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(new NotificationRunnable(), 0, 4 * 60, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(new NotificationRunnable(), 0, 9 * 60, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(new NotificationRunnable(), 0, 13 * 60, TimeUnit.SECONDS);
//Launching application first time
NotificationApp.runFromScheduledExecutor();
}
}
NotificationRunnable.java
public class NotificationRunnable implements Runnable{
@Override
public void run() {
Platform.runLater(() -> {
NotificationApp.playAnimation();
});
System.out.println("Done");
}
}
Notification.java
public class NotificationApp extends Application {
public static void main(String[] args) {
launch(args);
}
static Stage primaryStage = null;
static MediaPlayer mediaPlayer = null;
@Override
public void start(Stage primaryStage) {
// Create a custom dialog with an ImageView
Image gifImage = new Image(String.valueOf(new File("img/giphy.gif"))); // Replace with your GIF file path
ImageView gifImageView = new ImageView(gifImage);
Pane pane = new Pane(gifImageView);
Scene scene = new Scene(pane);
// Set stage properties
primaryStage.initStyle(StageStyle.TRANSPARENT); // Hide the window decoration
primaryStage.setAlwaysOnTop(true);
// Determine screen dimensions
double screenWidth = Screen.getPrimary().getVisualBounds().getWidth();
double screenHeight = Screen.getPrimary().getVisualBounds().getHeight();
double stageWidth = gifImage.getWidth();
double stageHeight = gifImage.getHeight();
// Set the stage position to the right corner
double xOffset = screenWidth - stageWidth;
double yOffset = screenHeight - stageHeight;
primaryStage.setX(xOffset);
primaryStage.setY(yOffset);
primaryStage.setScene(scene);
this.primaryStage = primaryStage;
Media sound = new Media(new Test().getClass().getResource("/snd/Notification.mp3").toExternalForm());
mediaPlayer = new MediaPlayer(sound);
//Play animation and Sound during application start
Platform.runLater(() -> {
playAnimation();
});
}
public static void playAnimation(){
Platform.runLater(() -> {
mediaPlayer.play();
primaryStage.show();
});
// Schedule closing the stage after 5 seconds
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.schedule(() -> {
Platform.runLater(() -> {
mediaPlayer.stop();
primaryStage.close();
});
}, 5, TimeUnit.SECONDS);
}
public static void runFromScheduledExecutor() {
Application.launch(NotificationApp.class);
}
}
我试图通过调用playAnimation()从Runnable播放动画和声音。但此代码不播放动画,当我第一次启动应用程序,它播放动画和声音按requirment,但第二次不工作。
1条答案
按热度按时间fykwrbwg1#
我将删除所有使用
static
字段,并删除所有使用ScheduledExecutorService。我意识到静态字段是必要的,因为Test的
main
方法无法访问JavaFX创建的NotificationApp示例,但更好的方法是只有一个main方法,因此您无需担心从其他类访问NotificationApp示例。如果您希望NotificationApp能够执行不同的操作,请使用其命令行参数。使用PauseTransition的setOnFinished方法而不是ScheduledExecutorService.schedule,这将消除对Platform.runLater的需要。不使用ScheduledExecutorService.scheduleAtFixedRate,而是使用单个KeyFrame创建一个时间轴,其侦听器执行该任务。
PauseTransition和时间轴的事件处理程序在JavaFX应用程序线程中调用,因此不需要Platform.runLater。
可以这样调用应用程序:
像
2m
这样的参数的含义在Duration.valueOf的文档中有解释。注意,这是javafx.util.Duration类,而不是java.time.Duration。**注意:**使用2分钟的间隔已经保证通知将每4分钟显示一次。同时显示2分钟 * 和 * 4分钟意味着每隔4分钟,两个通知将同时显示,彼此重叠。而且,正如您可能想象的那样,指定2分钟和9分钟意味着每18分钟将同时出现两个通知。如果同时设置2分钟和13分钟,则意味着每26分钟将同时出现两个通知。
在测试时,您可能应该只指定单个间隔,如
2m
。