4

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.

yizzlez
  • 8,757
  • 4
  • 29
  • 44
Whired
  • 259
  • 1
  • 11
  • What is the problem with making your own utility method which accepts a `Runnable` and perform it on the correct `Thread`. Saves you the if-else construct. Avoiding the `Runnable` will be difficult – Robin Mar 20 '12 at 22:29
  • thats true, everything is in the API, please edit your question with [SSCCE](http://sscce.org/), thank for [down_voting](http://stackoverflow.com/a/6839430/714968), look like as you on same dark as in your prevoius question :-) – mKorbel Mar 20 '12 at 22:29
  • @mKorbel, I don't believe your answer given in my previous question was correct. Time will not change this fact, and bringing it up here is only spam. Robin, That is what I'm doing now, it just seems a bit silly is all. – Whired Mar 20 '12 at 22:53
  • @Whired right `seems a bit silly is all` see my answer here – mKorbel Mar 20 '12 at 23:06
  • This bugs me too. If they were going to bother adding a check for it inside `invokeAndWait()`, why didn't they just call `runnable.run()` for us instead of throwing an exception? – Hakanai Mar 21 '14 at 02:11

3 Answers3

3

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

There isn't.

Whired
  • 259
  • 1
  • 11
2

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

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I'm not sure I understand the point of your example. When calling `repaint()`, the EDT would call `paint()`, not `isThereReallyEDT()`. I'm not afraid that the EDT is still alive after a call that uses it, I simply have other things to do that rely on the completion of the task, but shouldn't (always) necessarily be called from the EDT. – Whired Mar 20 '12 at 23:39
  • @Whired if is EDT empty .... and all output are done in rellated APIs, including potential output to the GUI (output to the GUI isn't conditions) then EDT is inactive and returns `false`, you can replace repaint(), paint() with e.g. pack(), add/remove JComponent(s), setText, Backgound/Foregroung, borders.... – mKorbel Mar 20 '12 at 23:45