将对象传递给另一个线程

时间:2015-03-18 17:55:41

标签: java multithreading swing

我正在创建一个GUI应用程序,在后台我想运行一个额外的任务。我将粘贴一些代码,以防止粘贴由Swing生成的一堆代码,我将保留一些部分,假设window.java正在按预期工作。

window.java:

public class window {
frame = new JFrame();
JLabel lbl1 = new JLabel("Start Counter");
frame.add(lbl1);

Thread counter = new Thread(new counter());
    counter.start();
}

counter.java

public class regCheck extends window implements Runnable
{

public void run()
{
    int i = 0;
    while (true)
    {
        window.lbl1.setText(i);
        try {Thread.sleep(1000);}
            catch (InterruptedException e) {e.printStackTrace();}
        i++;
    }
}
}

我想要这个例子做的是在窗口中创建一个标签并向上计数直到程序关闭。 这里简单的答案就是说“传入Jlabel”,但实际上我有很多事情需要改变而不仅仅是标签。

行“window.lbl1.setText(i);”在这里不起作用,只是为了说明我想要实现的目标。

2 个答案:

答案 0 :(得分:2)

使用MVC模式。创建一个具有计数器的模型,该计数器使用setValue()方法触发侦听器通知。您可以扩展java.util.Observable以使其更容易。添加getValue()方法以检索新计数。使得setter和getter同步以保证线程安全。

现在您的线程可以传递模型的一个实例,并调用setValue()来更新其run()方法中的值。

最后,您的视图可以传递给模型的同一个实例,并为其添加一个侦听器。为了使您的视图更容易实现java.util.Observer。在视图中的侦听器update()回调中,调用模型的getValue()并使用return作为setText()的参数。由于未从AWT事件调度程序线程调用侦听器更新,因此必须使用setText()调用javax.swing.SwingUtilities.invokeLater()以满足Swing的线程安全要求。

答案 1 :(得分:1)

它实际上是架构问题,你可以将任何参数传递给其他线程,这个线程当然可以修改不同的标签,但我更喜欢另一种变体:

  1. 你有窗口,它有对象/控件并且可以操作它们
  2. 你有单独的线程,增加计数器
  3. 这个单独的线程应该通知主窗口对象有关更改,窗口对象应该相应地更改它的控件,例如更改一个或多个控件中的文本

    一个简单的变体是具有接口,如ICounterHandler和一个方法

    void onCounterChanged(int newCounterValue);
    

    计数器线程应该在构造函数中接受ICounterHandler,保存并在需要时调用此方法,最好是异步

    当然还有很多其他变种,但你可以从这个开始