已经尝试了一段时间了,但进展并不快。当我点击播放按钮(触发ActionEvent)时,我想在JFrame中更新/切换可行性的元素。然而,这些似乎只有在actionPerformed方法完成后才会更新。这就是我认为正在发生的事情,因为我的SoundPlayer对象的构造函数触发(Thread.sleep)s,导致明显的延迟。我确实在这里读到使用Thread.sleep()锁定GUI,但我在调用SoundPlayer之前更改了,所以我不认为这将是问题。
如下所示,我试着重新绘制JFrame的整体,以及单个元素。虽然我的println语句打印出了正确的时间,但直到SoundPlayer的延迟完成后,这些才会更新。
多线程已经越过我的脑海作为一个解决方案,虽然我不明白为什么我需要这样做。任何关于这件事的帮助都是感激的!
public void actionPerformed(ActionEvent e){
int channel = 0, volume = 0; //Assigned for safety.
String musicNotes = ""; //Will be filled with the under-input.
boolean willPlay = true; //Assumes will be played.
/*Stuff that makes 'willPlay' either true of false*/
//If nothing is wrong, plays the String!
if (willPlay) { //If above parameters are good...
badNums.setVisible(false);
prog.setVisible(true);
if (vis.isSelected())
prog.setText("Estimated duration: " + estiDuration(musicNotes)*(0.4) + "seconds");
else
prog.setText("Duration: " + estiDuration(musicNotes)*(0.3) + "seconds");
System.out.println("test");
repaint();
prog.repaint();
new SoundPlayer(channel, volume, musicNotes); //Plays the music!
} else {
vis.setVisible(false);
badNums.setVisible(true);
}
}
Swing是单线程的-所有用于绘制,事件等的代码…在这个线程(称为EDT)上运行。如果您有一个长时间运行的任务并将其放在EDT上,那么它在完成之前什么也做不了(注意,调用repaint
不会直接将Component
替换为repaint
,因此在此调用之后运行一些长时间的任务并不意味着Component
实际上会在此之前绘制自己)。如果你需要执行冗长的操作,在不同的Thread
中完成——这可以直接使用Thread或使用SwingWorker来完成。如果是前者,请确保使用SwingUtilities.invokeXXX