Java 将对象传递给另一个线程

Java 将对象传递给另一个线程,java,multithreading,swing,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());

我正在创建一个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);”一行在这里不起作用,它只是为了说明我想要实现的目标。

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

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

    一个简单的变体是有接口,比如带有一个方法的IConterHandler

    void onCounterChanged(int newCounterValue);
    
    计数器线程应该在构造函数中接受ICounterHandler,保存它并在需要时调用此方法,最好是异步的


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

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

    一个简单的变体是有接口,比如带有一个方法的IConterHandler

    void onCounterChanged(int newCounterValue);
    
    计数器线程应该在构造函数中接受ICounterHandler,保存它并在需要时调用此方法,最好是异步的


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

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

    一个简单的变体是有接口,比如带有一个方法的IConterHandler

    void onCounterChanged(int newCounterValue);
    
    计数器线程应该在构造函数中接受ICounterHandler,保存它并在需要时调用此方法,最好是异步的


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

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

    一个简单的变体是有接口,比如带有一个方法的IConterHandler

    void onCounterChanged(int newCounterValue);
    
    计数器线程应该在构造函数中接受ICounterHandler,保存它并在需要时调用此方法,最好是异步的


    当然还有很多其他的变体,但是您可以从这个开始使用MVC模式。创建一个模型,该模型的计数器具有激发侦听器通知的
    setValue()
    方法。您可以扩展
    java.util.Observable
    ,使之更容易实现。添加一个
    getValue()
    方法来检索新计数。为了线程安全,使setter和getter同步

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


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

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

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

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