Java Wait()、Notify()、计时器和Jbuttons
我甚至不知道如何处理这个问题,但在阅读了一些文章并进行了大量尝试(失败)后,我决定向社区寻求帮助。我打开了表格A,要求用户输入延迟表格B打开的时间。目前我正在使用Java Wait()、Notify()、计时器和Jbuttons,java,multithreading,swing,sleep,wait,Java,Multithreading,Swing,Sleep,Wait,我甚至不知道如何处理这个问题,但在阅读了一些文章并进行了大量尝试(失败)后,我决定向社区寻求帮助。我打开了表格A,要求用户输入延迟表格B打开的时间。目前我正在使用sleep()来执行此操作,但现在我想插入另一个对话框,以允许用户在计时器用完之前中断计时器并调出表格B。我认为正确的方法是使用wait()和notify(),但我似乎无法对众多的生产者和消费者模型的示例进行概括。非常感谢您的帮助。最简单的方法就是这样做 Thread a = new Thread(new Runnable(){
sleep()
来执行此操作,但现在我想插入另一个对话框,以允许用户在计时器用完之前中断计时器并调出表格B。我认为正确的方法是使用wait()
和notify()
,但我似乎无法对众多的生产者和消费者模型的示例进行概括。非常感谢您的帮助。最简单的方法就是这样做
Thread a = new Thread(new Runnable(){
public void run(){
//do whatever display
try{
Thread.sleep(timeToShowBform);
}
catch(InterruptedException ex){
//interrupted.
}finally{
//show form B
SwingUtilities.invokeLater(...)
}
});
class BRunnable implements Runnable{
public void run(){
//if clicked, then this runnable is called.
a.interrupt();
}
}
线程
a
假设在sleep
被阻塞,然后调用a.interrupt()
它唤醒a
这是javax.swing.Timer
的完美工作。有关详细信息,请参阅。这里有一个例子来指导你正确的方向
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.Timer;
导入javax.swing.*;
公共类TimerDemo扩展JFrame实现ActionListener{
私人定时器;
私有JButton jbDoSomethingDelayed;
私有JButton jbdoimmediate;
公共TimerDemo(){
setLayout(新的FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(“计时器演示”);
jbDoSomethingDelayed=新的JButton(“延迟做某事”);
jbdoimimmediately=newjbutton(“现在就做吧!”);
添加(jbDoSomethingDelayed);
添加(即时添加);
jbdoimimmediately.setEnabled(false);
定时器=新定时器(0,this);//我们稍后重写延迟
timer.setRepeats(false);//我们不希望它重复启动
jbDoSomethingDelayed.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件e){
String msg=“输入延迟和确认对话框”;
JSpinner spinner=新JSpinner(新SpinnerNumberModel(5,1,10,1));
对象[]内容=新对象[]{msg,微调器};
int showConfirmDialog=JOptionPane.showConfirmDialog(TimerDemo.this,内容,“选择”,JOptionPane.OK\u取消\u选项);
if(showConfirmDialog==JOptionPane.OK\u选项){
//重要部分
timer.setInitialDelay(((整数)spinner.getValue())*1000);
jbDoSomethingDelayed.setEnabled(false);
jbdoimimmediately.setEnabled(true);
timer.start();
}
}
});
jbdoimimmediately.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件e){
timer.stop();
onTimerTimeout();
}
});
包装();
setLocationRelativeTo(空);
}
已执行的公共无效操作(操作事件e){
//在美国东部夏令时由定时器呼叫,无需担心
onTimerTimeout();
}
私有void onTimerTimeout(){
jbDoSomethingDelayed.setEnabled(true);
jbdoimimmediately.setEnabled(false);
showConfirmDialog(这是“您现在已经完成了。不,真的…”,“完成了”,JOptionPane.DEFAULT\u选项,JOptionPane.INFORMATION\u消息);
}
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
TimerDemo demo=新的TimerDemo();
demo.setVisible(true);
}
});
}
}
不要阻止EDT(事件调度线程)-发生这种情况时,GUI将“冻结”。不要调用Thread.sleep(n)
为延迟的任务执行Swing计时器。有关更多详细信息,请参阅。这将显示EDT之外的表单,这可能不是一个好主意。@assylias Yes,这就是为什么我在上面为a
使用Thread
,而不是仅在runnable上。我要说的是,finally
块将在该线程上执行,而不是在EDT上执行。您应该只从EDT与GUI交互。