简体   繁体   中英

passing objects to another thread

i am creating a GUI application and in the background I want to run an additional task. I will paste some code, to prevent pasting a mess of code that was generated by Swing, I will leave some parts out, assume that the window.java is working as intended.

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++;
    }
}
}

what I want this example to do is create a label within a window and count upwards until the program is closed. The easy answer here is to say "pass in the Jlabel" however in reality I have multiple things that I need to change not just a label.

the line "window.lbl1.setText(i);" does not work here, it is just to illustrate what I want to achieve.

Use the MVC pattern. Create a model that has the counter with a setValue() method that fires a listener notification. You can extend java.util.Observable to make that easier to do. Add a getValue() method to retrieve the new count. Make the setter and getter synchronized for thread safety.

Now your thread can be passed an instance of the model and call setValue() to update the value in its run() method.

Finally, your view can be passed the same instance of the model and add a listener to it. To make it easier your view can implement java.util.Observer . In the listener update() callback within the view, call the model's getValue() and use the return as the argument to setText() . Since the listener update is not being invoked from the AWT event dispatcher thread, you have to call setText() using javax.swing.SwingUtilities.invokeLater() in order to meet the thread safety requirements of Swing.

it is actually architectural question, you can pass any arguments to other thread and this thread of course could modify different labels, but I prefer another variant:

  1. you have window, which has its objects/controls and can manipulate them
  2. you have separate thread which increase counter

this separate thread should notify main window object about changes and window object should change it's controls accordingly, for example change text in one or several controls

one simple variant is to have interface, like ICounterHandler with one method

void onCounterChanged(int newCounterValue);

counter thread should accept ICounterHandler in constructor, save it and call this method when needed, preferable asynchronous

of course there are many other variants, but you can start with this one

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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