简体   繁体   English

在Java中使用Swing GUI中的线程

[英]Using threads in Swing GUI in Java

I am using the following codes, to replace a JLabel each 0.5 seconds, with the same sentence but with another dot. 我使用以下代码,每0.5秒替换一个JLabel ,使用相同的句子,但使用另一个点。

    Runnable r1=new Runnable() {
        @Override
        public void run() {
            while(true){
                try {
                    connectionStatus.setText("Connection Established...");
                    Thread.sleep(500L);
                    connectionStatus.setText("Connection Established.");
                    Thread.sleep(500L);
                    connectionStatus.setText("Connection Established..");
                    Thread.sleep(500L);
                } catch (InterruptedException ex) {

                }
            }
        }
    };
Thread th1=new Thread(r1);
th1.start();

Is this the real purpose from using threads? 这是使用线程的真正目的吗? Does this affect the speed of the program? 这会影响程序的速度吗? If the thing that I'm doing is so stupid, is there any other way to do such stupid things? 如果我正在做的事情是如此愚蠢,还有其他方法来做这些愚蠢的事情吗?

Is this the real purpose from using threads? 这是使用线程的真正目的吗?

If you want these operations to run in parallel then the answer is yes 如果您希望这些操作并行运行,那么答案是肯定的

is there any other way to do such stupid things? 有没有其他办法做这种愚蠢的事情?

If you update your label at a fixed intervals then you should probably go for using Timer s instead 如果您以固定的时间间隔更新标签,那么您应该选择使用Timer

On a side note: 在旁注:

  • You should avoid using while(true) when doing multithreading, you should either define a stop boolean that you test in the loop or use Thread.interrupted() if you extend the Thread class 你应该避免在执行多线程时使用while(true) ,你应该定义一个在循环中测试的stop boolean,或者如果扩展Thread类,则使用Thread.interrupted()
  • When updating UI elements from non EDT thread, you should use SwingUtilities.invokeLater 从非EDT线程更新UI元素时,应使用SwingUtilities.invokeLater

Try using a Timer from Swing library instead. 尝试使用Swing库中的Timer It's generally a better idea to use these for GUI-related tasks. 将这些用于GUI相关任务通常是一个更好的主意。 This will especially come in handy when you try to use timed events on multiple components as all Timers share the same timer thread. 当您尝试在多个组件上使用定时事件时,这将特别派上用场,因为所有计时器共享相同的计时器线程。

It also provides a flexible and intuitive programming model based on listeners. 它还提供基于听众的灵活和直观的编程模型。

No need to reinvent the wheel. 无需重新发明轮子。

Timer tutorial 计时器教程

EDIT: 编辑:

A little followup on the wheel reinvention part. 对车轮改造部分进行了一些跟进。 You should also take Andrew Thompson's suggestion into consideration. 您还应该考虑Andrew Thompson的建议。 There are components in Swing that have been designed specifically to indicate progress. Swing中有一些组件专门用于指示进度。 It's unnecessary to do it using a label, as you're trying to do. 正如你所想的那样,没有必要使用标签来做。 Take a look at JProgressBar . 看看JProgressBar It's going to be simple and it will look more professional. 它会变得简单,看起来更专业。

First one suggestion, rather use something like this: 第一个建议,而是使用这样的东西:

while(!isStopped) {
  // do some work
}

With your approach you just created infinity loop. 通过您的方法,您只需创建无限循环。

Note: Have look at Java Timer . 注意:看看Java Timer It's very usefull and efficient. 它非常有用和高效。

There are several issues with this code. 这段代码有几个问题。

  1. Swing components should be accessed/updated on the Event Dispatch Thread and are not thread-safe. 应该在Event Dispatch Thread上访问/更新Swing组件,这些组件不是线程安全的。 So starting another Thread to update your JLabel is simply not done. 因此,启动另一个线程来更新JLabel根本就没有完成。 See the 'Concurrency in Swing' tutorial for more information 有关更多信息,请参阅“Swing中的并发”教程
  2. Even if you would call the code above on the EDT, you would not see any updates of the JLabel as the Thread.sleep would block the EDT, and avoiding a repaint. 即使您在EDT上调用上面的代码,您也不会看到JLabel任何更新,因为Thread.sleep会阻止EDT,并避免重绘。

So the solution is to use the javax.swing.Timer class, which allows to perform operations on the EDT at regular intervals, and does not block the EDT in between. 所以解决方案是使用javax.swing.Timer类,它允许定期在EDT上执行操作,并且不会阻止它们之间的EDT。 See also the Timer tutorial . 另请参阅Timer教程 As a side effect, using timers avoids the while(true) loop which would never end. 作为副作用,使用定时器可以避免永远不会结束的while(true)循环。

You can find a more complete answer here . 你可以在这里找到更完整的答案。

Try this, 尝试这个,

  1. You will need the above approach if your purpose is parallel processing . 如果您的目的是并行处理,则需要上述方法。

  2. You have given while (true) , which will lead to a Infinite loop, you must control it, its better to have a boolean variable to control the nos. 你给了while(true) ,这将导致一个无限循环,你必须控制它,最好有一个布尔变量来控制nos。 of iteration of the while loop. while循环的迭代。

  3. Keep you non-ui thread processing OUT of the Event Dispatcher Thread , else you will make the GUI hang till your thread has finished its run() method. 保持对事件调度程序线程的非ui线程处理 ,否则你将使GUI挂起,直到你的线程完成其run()方法。 In your case its Infinite, as while (true). 在你的情况下它的无限,同时(真实)。

  4. If you want to sync the non-ui work and ui work , then you can use Handler or Swing-Worker. 如果要同步 非ui工作和ui工作 ,则可以使用Handler或Swing-Worker。

  5. Last but not the least, Take a look at TimeTask , see this link 最后但并非最不重要,请看一下TimeTask ,看看这个链接

    http://enos.itcollege.ee/~jpoial/docs/tutorial/essential/threads/timer.html http://enos.itcollege.ee/~jpoial/docs/tutorial/essential/threads/timer.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM