如何在JavaSwing中实现空闲任务
我有一个GUI应用程序,它的速度越来越慢。我想开始介绍各种GUI任务的计时——然而,我们的许多GUI操作都会触发其他操作,然后“稍后调用”触发其他操作 最终,一切都安定下来,没有更多的事可做。此时,我想停止计时器并报告GUI“操作”花费了多长时间 我认为这样做的方法是实现一个名为如何在JavaSwing中实现空闲任务,java,swing,awt,event-dispatch-thread,awt-eventqueue,Java,Swing,Awt,Event Dispatch Thread,Awt Eventqueue,我有一个GUI应用程序,它的速度越来越慢。我想开始介绍各种GUI任务的计时——然而,我们的许多GUI操作都会触发其他操作,然后“稍后调用”触发其他操作 最终,一切都安定下来,没有更多的事可做。此时,我想停止计时器并报告GUI“操作”花费了多长时间 我认为这样做的方法是实现一个名为invokeOnceIdle(Runnable task)的方法。只有当AWTEventQueue为“空”时,该方法才会执行提供的任务。i、 e.提供的“任务”应该是队列中的最后一项 一种方法是,如果有一种方法可以指定S
invokeOnceIdle(Runnable task)
的方法。只有当AWTEventQueue为“空”时,该方法才会执行提供的任务。i、 e.提供的“任务”应该是队列中的最后一项
一种方法是,如果有一种方法可以指定SwingUtilities.invokeLater的“最低”优先级,但这是不可能的
接下来,我想看看是否可以“invokeLater”一个可运行的程序,它检查事件队列是否为“空”——但没有公开的方法来查看事件队列是否为空
执行此操作的最佳方法是什么?isEventDispatchThread
返回当前值AWTEventQueue
是否为空
- 如果当前的
AWTEventQueue
为空,则可以从发布新事件到事件队列
invokeAndWait()
和invokeLater
也一样
- 如果当前值
AWTEventQueue
不为空,则不能使用invokeAndWait()
仅invokeLater()
比如说
import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class IsThereEDT {
private ScheduledExecutorService scheduler;
private AccurateScheduledRunnable periodic;
private ScheduledFuture<?> periodicMonitor;
private int taskPeriod = 30;
private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
private Date dateRun;
private JFrame frame1 = new JFrame("Frame 1");
public IsThereEDT() {
scheduler = Executors.newSingleThreadScheduledExecutor();
periodic = new AccurateScheduledRunnable() {
private final int ALLOWED_TARDINESS = 200;
private int countRun = 0;
private int countCalled = 0;
private int maxCalled = 10;
@Override
public void run() {
countCalled++;
if (countCalled < maxCalled) {
if (countCalled % 3 == 0) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Push a new event to EDT");
frame1.repaint();
isThereReallyEDT();
}
});
} else {
if (this.getExecutionTime() < ALLOWED_TARDINESS) {
countRun++;
isThereReallyEDT(); // non on EDT
}
}
} else {
System.out.println("Terminating this madness");
System.exit(0);
}
}
};
periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS);
periodic.setThreadMonitor(periodicMonitor);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
isThereReallyEDT();
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.getContentPane().add(new JLabel("Hello in frame 1"));
frame1.pack();
frame1.setLocation(100, 100);
frame1.setVisible(true);
}
});
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame2 = new JFrame("Frame 2");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.getContentPane().add(new JLabel("Hello in frame 2"));
frame2.pack();
frame2.setLocation(200, 200);
frame2.setVisible(true);
isThereReallyEDT();
}
});
}
private void isThereReallyEDT() {
dateRun = new java.util.Date();
System.out.println(" Time at : " + sdf.format(dateRun));
if (EventQueue.isDispatchThread()) {
System.out.println("EventQueue.isDispatchThread");
} else {
System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that ");
}
if (SwingUtilities.isEventDispatchThread()) {
System.out.println("SwingUtilities.isEventDispatchThread");
} else {
System.out.println("There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that ");
}
System.out.println();
}
public static void main(String[] args) {
IsThereEDT isdt = new IsThereEDT();
}
}
abstract class AccurateScheduledRunnable implements Runnable {
private ScheduledFuture<?> thisThreadsMonitor;
public void setThreadMonitor(ScheduledFuture<?> monitor) {
this.thisThreadsMonitor = monitor;
}
protected long getExecutionTime() {
long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS);
return delay;
}
}
导入java.awt.EventQueue;
导入java.text.simpleDataFormat;
导入java.util.Date;
导入java.util.concurrent.*;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.swing.*;
公共课在这里{
专用ScheduledExecutorService调度器;
专用精确计划可重复周期;
专用计划未来周期监视器;
私人时间段=30;
私有SimpleDataFormat sdf=新SimpleDataFormat(“HH:mm:ss”);
私人日期运行;
私有JFrame frame1=新JFrame(“Frame 1”);
公共IsThereEDT(){
scheduler=Executors.newSingleThreadScheduledExecutor();
周期=新的AccurateScheduledRunnable(){
允许私人最终整数_延误=200;
私有int countRun=0;
私有int countCalled=0;
私有int maxCalled=10;
@凌驾
公开募捐{
countCalled++;
if(countCalled
使用您自己的事件队列,您可以轻松实现该目标。这是我做的一些东西,应该让你去做:
private static class MyEventQueue extends EventQueue {
private Deque<Runnable> onceIdle = new LinkedList<Runnable>();
public MyEventQueue() {
Toolkit.getDefaultToolkit().getSystemEventQueue().push(this);
}
public void runOnceIdle(Runnable toRun) {
onceIdle.addLast(toRun);
}
@Override
protected void dispatchEvent(AWTEvent event) {
super.dispatchEvent(event);
if (peekEvent() == null) {
for (Runnable toRun : onceIdle) {
toRun.run();
}
onceIdle.clear();
}
}
}
private stati