标签: event-dispatch-thread

在Java 7+中,在EDT之外使用Swing repaint()方法是否仍然安全?

我知道,repaint()即使使用Swing的线程模型,以前从任何线程调用和其他一些选定的方法都被认为是安全的,但是我最近在评论中告诉我并非如此.

谷歌发现很多旧的讨论说这是安全的,但最近没什么.所有过去曾经说过安全的官方参考文献似乎已经消失了,我在各种论坛上发现了一些人讨论它是如何不再安全的.

我找不到任何正式的东西来确认它是否存在 - 而且我真的希望看到一些解释改变逻辑的东西,如果它已被改变的话.考虑到破坏现有应用程序的风险有多严重,删除它似乎是一个非常奇怪的功能.

我真的在寻找一个官方参考链接(即Javadoc,oracle教程或源代码链接),说明这些方法是否可以安全地从任何线程调用.

这里提到这个问题:

在EDT之外安全使用Component.repaint()?

从现已消失的Sun页面中引用一句话:

以下JComponent方法可以安全地从任何线程调用:repaint(),revalidate()和invalidate().repaint()和revalidate()方法将事件派发线程的请求分别调用paint()和validate().

这符合我的理解,但我现在找不到那个页面或任何类似的页面,我看到几个人的未经证实的谣言说它不再安全.但另一方面,我找不到任何明确的说这个功能已经改变.

改变笔记

可能有助于解决这个问题的是Oracle关于Swing线程处理变化的官方声明.我发现了"Java 7中的更改"页面,但根本没有提到它,这些页面都没有以任何方式提及线程或EDT:

http://docs.oracle.com/javase/7/docs/technotes/guides/swing/enhancements-7.html

http://docs.oracle.com/javase/7/docs/technotes/guides/awt/enhancements-7.html

java swing multithreading repaint event-dispatch-thread

12
推荐指数
1
解决办法
1963
查看次数

防止在后台任务期间锁定Swing GUI

我有一个swing应用程序,它存储一个对象列表.当用户点击按钮时

我想对列表中的每个对象执行两个操作,然后一旦完成,将结果绘制在JPanel中.我一直在尝试使用SwingWorker,Callable和Runnable进行处理,但无论我做什么,在处理列表时(可能需要几分钟,因为它是IO绑定的),GUI被锁定.

我有一种感觉,这可能是我调用线程或其他东西的方式,还是可能与图形函数有关?这不是线程,因为它非常快.

我必须按顺序完成两个处理阶段,那么确保第二个阶段在第一个阶段等待的最佳方法是什么?我已经使用了join(),然后

while(x.isAlive())  
{  
        Thread.sleep(1000);  
}
Run Code Online (Sandbox Code Playgroud)

尝试确保这一点,但我担心这也可能是我的问题的原因.

我一直在寻找一些指针,但由于我找不到任何东西,我确信我在这里做了些蠢事.

java swing multithreading swingworker event-dispatch-thread

11
推荐指数
2
解决办法
1万
查看次数

抛出异常时EDT是否重启?

(下面的示例代码是自包含且可运行的,您可以尝试它,它不会崩溃您的系统:)

Tom Hawtin在这里评论了这个问题:为什么人们在事件队列上运行Java GUI

那:

EDT不太可能崩溃.在EDT调度中抛出的未经检查的异常被捕获,转储并且线程继续.

有人可以解释我这里发生了什么(每次你点击"抛出一个未经检查的异常"按钮,有意地执行除以零):

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class CrashEDT extends JFrame {

    public static void main(String[] args) {
        final CrashEDT frame = new CrashEDT();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing( WindowEvent e) {
                System.exit(0);
            }
        });
        final JButton jb = new JButton( "throw an unchecked exception" );
        jb.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                System.out.println( "Thread ID:" + Thread.currentThread().getId() );
                System.out.println( 0 …
Run Code Online (Sandbox Code Playgroud)

java exception event-dispatch-thread

11
推荐指数
2
解决办法
1476
查看次数

制作一个显示"请等待"JDialog的摇摆线程

问题是这样的:
我正在运行一个swing应用程序,在某个时刻,对话框需要插入用户名和密码并按下"ok".
我希望当用户按下"ok"时,swing应用程序按此顺序执行:

  1. 打开"请等待"JDialog
  2. 进行一些操作(最终显示其他一些JDialog或JOptionPane)
  3. 当它完成操作时关闭"请等待"JDialog

这是我在okButtonActionPerformed()中编写的代码:

private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { 
    //This class simply extends a JDialog and contains an image and a jlabel (Please wait)
    final WaitDialog waitDialog = new WaitDialog(new javax.swing.JFrame(), false);    
    waitDialog.setVisible(true);
    ... //Do some operation (eventually show other JDialogs or JOptionPanes)
    waitDialog.dispose()
}
Run Code Online (Sandbox Code Playgroud)

这段代码显然不起作用,因为当我在同一个线程中调用waitDialog时,它会阻塞所有代码直到我不关闭它.
所以我试着在另一个线程中运行它:

private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { 
    //This class simply extends a JDialog and contains an image and a jlabel (Please wait)
    final WaitDialog waitDialog = new WaitDialog(new javax.swing.JFrame(), false);    
    SwingUtilities.invokeLater(new Runnable() …
Run Code Online (Sandbox Code Playgroud)

java swing multithreading event-dispatch-thread

11
推荐指数
2
解决办法
3万
查看次数

在运行时Swing验证Event Dispatch Thread上的代码

是否有任何库可以检测代码以验证在事件调度线程上调用Swing组件上调用的方法?编写一些用于执行此操作的基本代码可能不会太困难,但我确信有其他人处理的边缘情况.我在运行时寻找这个,而不是单元测试.

java swing event-dispatch-thread

10
推荐指数
1
解决办法
3533
查看次数

何时使用SwingUtilies.invokeAndWait/invokeLater

我在某处看到,对于影响gui视觉效果的任何线程,它应该使用SwingUtilities.invokeAndWait/invokeLater在EDT中运行

对于一个基本的gui,是否有必要new SwingGUI().setVisible(true);使用invokeAndWait 放置类似于EDT的内容?只是为了展示?

这算数了吗?

java concurrency swing multithreading event-dispatch-thread

10
推荐指数
2
解决办法
5149
查看次数

Java Swing - 在EDT上运行

关于Swing和使用EDT进行GUI更新,我有几个问题.我刚刚开始阅读这些内容,所以我是这个领域的初学者:

  1. 在EDT上运行需要哪些操作?如果他们不这样做,只是提出一个例外?
  2. 我们实际上在EDT上有没有特定的时间?
  3. 如果我们使用我们安排任务SwingUtilities.invokeLater我们将它排入GUI更新任务的当前队列对吗?
  4. 访问上面的队列我猜是同步的,或者使用了一些并发集合,但是如果我从两个后台线程调度两个GUI更新任务,就不可能说先添加哪一个?例如,如果线程1 FIRST提交将JLable的文本设置为"是"的任务,然后,短时间之后,第二个线程出现并提交将该值设置为"no"的任务,我们是否保证结果将是"是",或者仅仅是操作系统如何安排这些事情的问题?
  5. SwingWorker究竟是如何确保done()在EDT上运行该方法的?它设置以下代码:

      future = new FutureTask<T>(callable) {
                   @Override
                   protected void done() {
                       doneEDT();
                       setState(StateValue.DONE);
                   }
               };
    
    Run Code Online (Sandbox Code Playgroud)

所以我想知道FutureTask是否以某种方式确保invokeLater被调用?

谢谢你的所有答案.

java swing event-dispatch-thread

10
推荐指数
2
解决办法
5564
查看次数

JavaFx对SwingUtilities.invokeLater的响应

所以我知道JavaFx在使用线程时更新GUI的方法称为Task,但代码的工作方式是否相似或存在差异.让我举个例子:

GUI之外的另一个类作为线程运行

public void run(){
    while (socket.isConnected()) {
        String x = input.next();
        System.out.println(x);
        mg.updateChat(x)
    }
}
Run Code Online (Sandbox Code Playgroud)

在实际的GUI里面

public void updateChat(final String input){
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            txtChat.setText(input); 
        }
    }); 
}
Run Code Online (Sandbox Code Playgroud)

任务的工作方式是否完全相同?或者是否存在差异,是否有如何修改此代码以在JavaFx项目中工作?

java swing javafx mixing event-dispatch-thread

10
推荐指数
1
解决办法
8915
查看次数

如何选择AWT-EventQueue线程,当有多个线程时

我使用DLL注入和一些jni技巧成功地在运行的Oracle Forms应用程序中注入了我自己的Java代码.(Windows 7,32位,Oracle Forms 11,JRE Java 8)

我能够遍历组件树,并在一些基本的Java对象(例如来自类的对象)中查询和设置值 oracle.forms.ui.VTextField

当我试图模拟用户点击时,我陷入了困境 oracle.apps.fnd.ui.Button

我尝试了两件事:

  1. 调用类的simulatePush方法AbstractButton
  2. 调用类的activate方法PushButton

(这两个类在类层次结构中Button)

结果相同:1.首先,它工作正常:当按钮是"搜索"按钮时,搜索完成并显示结果.然后,它立刻打破了应用程序,弹出一个说法FRM-92100 Your connection to the Server was interrupted.

从那里,应用程序挂起.

更新: 似乎导致与服务器断开连接的错误是:

java.lang.SecurityException:此KeyboardFocusManager未安装在当前线程的上下文中java.awt.KeyboardFocusManager.checkCurrentKFMSecurity(未知源)位于java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer上的java.awt.KeyboardFocusManager.getGlobalFocusOwner(未知源)中(未知来源)来自)java.awt.Component.requestFocusHelper的java.awt.Component.requestFocusHelper(未知来源)的sun.awt.windows.WComponentPeer.processSynchronousLightweightTransfer(本地方法)at sun.awt.windows.WComponentPeer.requestFocus(未知来源) oracle.forms.hand处理器上oracle.forms.handler.UICommon.updateFocus(未知来源)位于oracle.forms.hand处理器上的java.awt.Component.requestFocus(未知源)处的(未知源)位于oracle.forms.hand.handler.Ja上的oracle.forms.hand.hand上的oracle.forms.hand.hand上的oracle.forms.hand.hand.Ter上的oracle.forms.hand.hand.Th上的oracle.forms.handler.Ja上的未知来源(未知来源).UICommon.setFVP(未知来源)rce)at oracle.forms.engine.Uuomom.onUpdate(Unknown Source)at oracle.forms.engine.Runform.onUpdateHandler(Unknown Source)at oracle.forms.engine.Runform.processMessage(Unknown Source)at oracle.forms.engine oracle.forms.engine.Runform.onMessage(未知来源)位于oracle.forms.engine.Runform.processEventEnd(未知来源)的oracle.forms.engine.Runform.onMessage(未知来源)的.runform.processSet(未知来源) at oracle.ewt.lwAWT.LWComponent.redispatchEvent(Unknown Source)at oracle.ewt.lwAWT.LWComponent.processEvent(Unknown Source)at oracle.ewt.button.PushButton.activate(Unknown Source)at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native方法)at sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)at sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源),位于CustomAWT.run上的java.lang.reflect.Method.invoke(未知来源)(CustomAWT.java) :34)在java.awt.EventQueue.dispatchEventImpl(未知Sou)的java.awt.event.InvocationEvent.dispatch(未知来源)rce)java.awt.EventQueue.access $ 400(未知来源)java.awt.EventQueue $ 2.run(未知来源)java.awt.EventQueue $ 2.run(未知来源)java.security.AccessController.doPrivileged(原始方法)java.security.AccessControlContext $ 1.doIntersectionPrivilege(未知来源)java.awt.EventDispatchEvent(未知来源)java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源)java.awt.EventDispatchThread.pumpEventsForFilter(未知) java.awt.EventDispatchThread.run上的java.awt.EventDispatchThread.pumpEvents(未知来源)java.awt.EventDispatchThread.run(未知来源)java.awt.EventDispatchThread.pumpEventsForHierarchy(未知来源)

我的代码在这里:CustomAWT.run(CustomAWT.java:34)并且被调用invokeLater.问题可能是:在调用oracle.ewt.button.PushButton.activate方法时,我不在正确的EDT中.

使用Java控制台中的"列出线程",我得到了:

Dump thread list …
Run Code Online (Sandbox Code Playgroud)

java java-native-interface oracleforms event-dispatch-thread

10
推荐指数
1
解决办法
1169
查看次数

问题:创建一个非常准确的Swing Timer

为了SwingTimer准确,我喜欢@Tony Docherty On CR提出的逻辑和例子.这是链接.

为了突出显示给定的单词,一次又一次,总会有几微秒的延迟.如果我要突出显示单词:"你好怎么样",每个单词的值分别为(延迟):200,300,400 ms,那么计时器的实际时间总是更多.说而不是200毫秒,它需要216毫秒.像这样,如果我有很多话......最后,额外的延迟是显而易见的.

我必须强调每个字母说:'h''''''''''0'每个应该得到200 /长度(即5)=约40毫秒.设置每个字母后的延迟.

我的逻辑是,在当前时间说startTime,就在开始这个过程之前.另外,计算totalDelaytotalDelay + = delay/.length().

现在检查条件:( startTime+totalDelay-System.currentTime)如果这是-ve,这意味着时间消耗更多,所以跳过这封信.检查直到有一个正的延迟.这意味着我要添加时间到现在,并用它开始时的过程所花费的时间差来检查它.

这可能导致跳过以突出显示字母.

但有些事情是错的.什么,我很难说出来.这可能是循环事情的一些问题.我已经看到它进入循环(检查时间是否为-ve)只是两次.但事实并非如此.而且我也不确定是否会设置下一次延迟.有任何想法吗?

这是一个SSCCE:

    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.lang.reflect.InvocationTargetException;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextPane;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DefaultStyledDocument;
    import javax.swing.text.StyleConstants;
    import javax.swing.text.StyledDocument;

    public class Reminder {
        private static final String TEXT = "arey chod chaad ke apnee saleem ki gali anarkali disco chalo";
        private static final String[] WORDS = TEXT.split(" …
Run Code Online (Sandbox Code Playgroud)

java swing timer event-dispatch-thread

9
推荐指数
2
解决办法
2990
查看次数