Java JFrame:在事件期间更新GUI(不在计时器内)
我已经试了一段时间了,走得不快。当我点击我的播放按钮(触发ActionEvent)时,我想更新/切换JFrame中的元素。但是,这些似乎只有在actionPerformed方法完成后才更新。我认为这是因为SoundPlayer对象的构造函数触发了(Thread.sleep),导致了明显的延迟。我确实读过使用Thread.sleep()锁定GUI的文章,但我在调用SoundPlayer之前进行了更改,所以我认为这不是问题所在 如下图所示,我尝试了重新绘制JFrame的总体以及单个元素。虽然我的println语句在正确的时间打印一个文件,但这些文件直到SoundPlayer的延迟完成后才会更新 多线程作为一种解决方案出现在我的脑海中,尽管我不明白为什么我需要这样做。在此问题上的任何帮助都将不胜感激Java JFrame:在事件期间更新GUI(不在计时器内),java,swing,user-interface,repaint,actionevent,Java,Swing,User Interface,Repaint,Actionevent,我已经试了一段时间了,走得不快。当我点击我的播放按钮(触发ActionEvent)时,我想更新/切换JFrame中的元素。但是,这些似乎只有在actionPerformed方法完成后才更新。我认为这是因为SoundPlayer对象的构造函数触发了(Thread.sleep),导致了明显的延迟。我确实读过使用Thread.sleep()锁定GUI的文章,但我在调用SoundPlayer之前进行了更改,所以我认为这不是问题所在 如下图所示,我尝试了重新绘制JFrame的总体以及单个元素。虽然我的pr
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
不会直接repaint
组件,因此在此调用之后运行一些长时间的任务并不意味着组件实际上会在之前进行绘制)。如果需要执行较长的操作,请在不同的线程中执行-这可以直接使用或使用来完成。如果是前者,请确保使用SwingUtilities.invokeXXX
将所有对Swing的调用发送到EDT,谢谢。在尝试合并SwingWorker之后,我又回到了Thread,我确实知道这一点,它在没有太多额外编辑的情况下发挥了巨大的作用!现在,我应该能够重新审视我最初的目标,即在我的声音播放过程中更新字符串处理的进度!