Java API “Run on EDT if not on EDT”

2019-05-07 15:35发布

Just a musing about some repetitive code I have:

Runnable run = new Runnable() {
  @Override
  public void run() {
    // Some EDT code
  }
};

if (!EventQueue.isDispatchThread()) {
  SwingUtilities.invokeAndWait(run);
} else {
  run.run();
}

It's not terribly annoying, but it seems like there would be some proprietary function that checks this for you, although I haven't found it.

3条回答
Lonely孤独者°
2楼-- · 2019-05-07 16:15

Excluding Substance Look and Feel I never needed to use invokeAndWait or testing for isDispatchThread / isEventDispatchThread,

Substance Look and Feel required in some special cases usage of invokeAndWait for JTable, JTree, SwingX's TreeTable, really not important in this case

delay 30seconds is required for "expiring of EDT" then you can creating n_Threads, each of then can alive EDT, simple, without special effort, another limit could be Latency from Native OS

output

run:
                         Time at : 00:00:45
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

                         Time at : 00:00:45
EventQueue.isDispatchThread
SwingUtilities.isEventDispatchThread

                         Time at : 00:00:45
EventQueue.isDispatchThread
SwingUtilities.isEventDispatchThread

                         Time at : 00:01:15
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

Push a new event to EDT
                         Time at : 00:01:45
EventQueue.isDispatchThread
SwingUtilities.isEventDispatchThread

                         Time at : 00:02:15
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

                         Time at : 00:02:45
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

Push a new event to EDT
                         Time at : 00:03:15
EventQueue.isDispatchThread
SwingUtilities.isEventDispatchThread

                         Time at : 00:03:45
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

                         Time at : 00:04:15
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

Push a new event to EDT
                         Time at : 00:04:45
EventQueue.isDispatchThread
SwingUtilities.isEventDispatchThread

Terminating this madness
BUILD SUCCESSFUL (total time: 4 minutes 31 seconds)

from

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;
    }
}

you can do everything, changing orders, methods, freezing by Thread.sleep(int), in all cases is possible to alive EDT in the assumed moment, nothing shadowed, any miracles, wrong code that calling to the Heavens instead of to the EDT

查看更多
Anthone
3楼-- · 2019-05-07 16:18

it seems like there would be some proprietary function that checks this for you

There isn't.

查看更多
登录 后发表回答