SwingUtilities.invokeLater() ou EventQueue.invokeLater()

Pessoal, sempre pesquisei sobre ambos, mas nunca encerrei minha dúvida: qual devemos utilizar? :shock:
Pessoalmente, só utilizo o SwingUtilities e somente quando percebo atrasos nos eventos em determinadas situações como uso da barra de rolagem…
Praticamente a poucos meses comecei a utilizar na exibição de JFrame`s, porém na mais pura realidade, sem saber o porque e quais seus efeitos que não os vejo?

Alguém pode passar uma visão maior de sua experiência quanto à utilização de cada um e em quais situações são mais apropriados ao real uso?
Já li em outros lugares que são a mesma coisa (Como assim? :roll: ) sendo que EventQueue é mais rápido…

[size=14]É isso aí, tenho essas dúvidas senhores, aguardarei.
Excelente 2012, um abraço![/size]

Sobre a diferença entre SwingUtilities.invokeLater e EventQueue.invokeLater, veja a implementação do SwingUtilities.invokeLater (retirada do próprio Java):

public class SwingUtilities {
    /**
     * Causes <i>doRun.run()</i> to be executed asynchronously on the
     * AWT event dispatching thread.  This will happen after all
     * pending AWT events have been processed.  This method should
     * be used when an application thread needs to update the GUI.
     * In the following example the &lt;code&gt;invokeLater&lt;/code&gt; call queues
     * the &lt;code&gt;Runnable&lt;/code&gt; object &lt;code&gt;doHelloWorld&lt;/code&gt;
     * on the event dispatching thread and
     * then prints a message.
     * &lt;pre&gt;
     * Runnable doHelloWorld = new Runnable() {
     *     public void run() {
     *         System.out.println("Hello World on " + Thread.currentThread());
     *     }
     * };
     *
     * SwingUtilities.invokeLater(doHelloWorld);
     * System.out.println("This might well be displayed before the other message.");
     * &lt;/pre&gt;
     * If invokeLater is called from the event dispatching thread --
     * for example, from a JButton's ActionListener -- the <i>doRun.run()</i> will
     * still be deferred until all pending events have been processed.
     * Note that if the <i>doRun.run()</i> throws an uncaught exception
     * the event dispatching thread will unwind (not the current thread).
     * <p>
     * Additional documentation and examples for this method can be
     * found in
     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How to Use Threads</a>,
     * in &lt;em&gt;The Java Tutorial&lt;/em&gt;.
     * <p>
     * As of 1.3 this method is just a cover for &lt;code&gt;java.awt.EventQueue.invokeLater()&lt;/code&gt;.
     * <p>
     * Unlike the rest of Swing, this method can be invoked from any thread.
     *
     * @see #invokeAndWait
     */
    public static void invokeLater(Runnable doRun) {
        EventQueue.invokeLater(doRun);
    }
}

Isso responde sua pergunta?

Agora, para que servem esses métodos? O Swing não é multi-thread. Portanto, é incorreto atualizar componentes em threads separadas. O método EventQueue.invokeLater é uma forma thread-safe de enfileirar um “pedido” à thread do Swing, para que esta execute uma ação. Essa ação pode ser atualizar uma caixa de textos, uma barra de progresso, etc. Poucos métodos do Swing são thread-safe e, quando o são, o Swing documenta esse fato no Javadoc.

Para mais informações:
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Abaixo uns artigos antigos, mas são legais para entender o conceito e como a coisa evoluiu até hoje:
http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html
http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html
http://java.sun.com/products/jfc/tsc/articles/threads/threads3.html

Fala Godoy, [quote=ViniGodoy]Isso responde sua pergunta?[/quote]
Claro que responde! :smiley: Parabéns mais uma vez.
Os links são excelentes! O primeiro listado já havia visto anteriormente quando buscava informação sobre o invokeLater.

Só que agora fiquei com uma nova dúvida: como faço para que um método que me devolve um determinado número aguarde o término de todos os outros eventos que estão acontecendo para que o retorno (resposta) não me devolva um número falso (ou desatualizado devido uma mudança realizada por algum evento que ocorreu entre a chamada do método e a resposta) ? Exemplo: um método que me devolve a posição de um scroll é chamado no momento que este scroll está se movendo… ele precisa aguardar o scroll parar para retornar o valor verdadeiro daquela posição no momento em que parou. Como fazer isso para que o método retorne esse valor sem utilizar uma thread-safe? Impossível, não? Só usando o SwingUtilities.invokeLater() ou EventQueue.invokeLater()? :idea:

:arrow: Uso de threads no swing é pecado, ok. Mas, e de thread-safe? Também é?

Valeu demais por estar desprendendo de seu tempo em me ajudar, fico sem palavras…
Muito bacana sua iniciativa em ajudar as pessoas da melhor maneira possível. Sucesso e saúde neste novo ano! :wink:

Se você estiver rodando só na thread do Swing, isso não será problema. Mas geralmente eventos desse tipo tem um campo para indicar que o usuário parou de mover (quando ele solta o mouse).

[quote=pedromuyala] :arrow: Uso de threads no swing é pecado, ok. Mas, e de thread-safe? Também é?

Essa pergunta não faz sentido. Você tem certeza que sabe o que é thread-safe?

Opa Godoy, de fato, a segunda pergunta que fiz falei bobagem, nada a ver com nada, me desculpe.

Quanto a resposta da primeira pergunta, só posso mais uma vez agradecê-lo! A dificuldade acontece geralmente quando o método chamado para retornar a posição do scroll que, devido ainda não ter terminado seu último update (ou seja, ainda está se movimentando na tela para a posição final), acaba me retornando um valor “resultante do intervalo no momento em que estava se atualizando” e não da “posição final do seu update”, pegou a ideia? Digamos que o scroll vai se movimentar em um intervalo do ponto x=10 até x=2300 após clicar no botão que, ao receber o evento no actionPerformed vai chamar o método que retorna a posição desse mesmo scroll, que deverá ser a final (quando ele já estiver na posição final, que não conhecemos). O que acaba acontecendo? O valor retornado não é 2300 mas sim um valor desse intervalo (900, 1346, 2998,…), sacou? :roll:

Forte abraço, muito sucesso :wink: