Java JFrame:在事件期间更新GUI(不在计时器内)



已经尝试了一段时间了,但进展并不快。当我点击播放按钮(触发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

将对Swing的任何调用分派给EDT

相关内容

  • 没有找到相关文章

最新更新