Multithreading for the user interface

Source: Internet
Author: User
Tags continue sleep

Now, we may be able to solve the problem in Counter1.java with a single thread. One trick is to put a "subtask" in the Run () method of one thread-that is, the loop in Go (). Once the user presses the Start button, the thread starts, but immediately ends the thread creation. Thus, while the thread is still running, the main work of the program can continue (wait and respond to the user interface's events). The following is the specific code:
 

: Counter2.java//A responsive user interface with threads import java.awt.*;
Import java.awt.event.*;

Import java.applet.*;
  Class Separatesubtask extends Thread {private int count = 0;
  Private Counter2 C2;
  Private Boolean runflag = true;
    Public Separatesubtask (Counter2 c2) {this.c2 = C2;
  Start ();
  public void Invertflag () {runflag =!runflag;}
     public void Run () {while (true) {try {sleep (100);
    catch (Interruptedexception e) {} if (Runflag) C2.t.settext (integer.tostring (count++));
  }} public class Counter2 extends Applet {TextField t = new TextField (10);
  Private Separatesubtask sp = null;
  Private button onoff = New button ("Toggle"), start = New button ("Start");
    public void Init () {Add (t);
    Start.addactionlistener (New Startl ());
    Add (start);
    Onoff.addactionlistener (New Onoffl ());
  Add (OnOff); Class Startl implements ActionListener {public void actionperformed (ActionEvent e) {if (sp = = null) SP = new Separatesubtask (counter2.this);
        Class ONOFFL implements ActionListener {public void actionperformed (ActionEvent e) {if (SP!= null)
    Sp.invertflag ();
    } public static void Main (string[] args) {Counter2 applet = new Counter2 ();
    Frame aframe = new Frame ("Counter2"); Aframe.addwindowlistener (New Windowadapter () {public void windowclosing (WindowEvent e) {System.
        Exit (0);
    }
      });
    Aframe.add (applet, borderlayout.center);
    Aframe.setsize (300,200);
    Applet.init ();
    Applet.start ();
  Aframe.setvisible (TRUE); }
} ///:~


Now, Counter2 becomes a fairly straightforward program, and its only task is to set up and manage the user interface. But if the user presses the Start button now, it does not actually call a method. Instead of creating a thread for the class, you create the Separatesubtask and then continue Counter2 the event loop. Note that the handle of the separatesubtask is saved so that when we press the OnOff button, we can switch the Runflag (run flag) that is located inside the separatesubtask normally. The thread then starts (when it sees the flag), and then aborts itself (it can also be separatesubtask as an internal class to achieve this). The
Separatesubtask class is a simple extension of thread, with a builder (which holds the Counter2 handle and then runs the thread by calling start) and a run ()-- Essentially contains the code within the Go () of the Counter1.java. Because Separatesubtask knows that he holds a handle to a Counter2, it can intervene when needed and access the Testfield of Counter2 (text field). The
Press the OnOff button to get the correct response almost immediately. Of course, this response is not "immediate", after all, unlike the one that is driven by interrupts. Only the thread has the CPU execution time, and notice that the tag has changed before the counter stops.

1. Improve the code with the internal class the following is a digression, please pay attention to the Separatesubtask and Counter2 of the combination of behavior. Separatesubtask with Counter2 "intimately"-it must hold a handle to its own "parent" Counter2 object so that it can be recalled and manipulated. But two classes are not really merged into a single class (although in the next section, we'll talk about Java does provide a way to merge them), because they do different things and are created at different times. However, they are still tightly coupled (or, more precisely, "federated"), so the code of the program is somewhat clumsy. In this case, an inner class can significantly improve the readability and execution efficiency of the code:
 

: Counter2i.java//Counter2 using a inner class for the thread import java.awt.*;
Import java.awt.event.*;

Import java.applet.*;
    public class Counter2i extends Applet {Private class Separatesubtask extends Thread {int count = 0;
    Boolean runflag = true;
    Separatesubtask () {Start ();}
       public void Run () {while (true) {try {sleep (100);
      catch (Interruptedexception e) {} if (Runflag) T.settext (integer.tostring (count++));
  }} private Separatesubtask sp = null;
  Private TextField t = new TextField (10);
  Private button onoff = New button ("Toggle"), start = New button ("Start");
    public void Init () {Add (t);
    Start.addactionlistener (New Startl ());
    Add (start);
    Onoff.addactionlistener (New Onoffl ());
  Add (OnOff);
        Class Startl implements ActionListener {public void actionperformed (ActionEvent e) {if (sp = null)
    SP = new Separatesubtask (); }} Class ONOFFL implements ActionListener {public void actionperformed (ActionEvent e) {if (SP!= null) SP.RUNFL AG =!sp.runflag;
    Invertflag ();
    } public static void Main (string[] args) {counter2i applet = new Counter2i ();
    Frame aframe = new Frame ("Counter2i"); Aframe.addwindowlistener (New Windowadapter () {public void windowclosing (WindowEvent e) {System.
        Exit (0);
    }
      });
    Aframe.add (applet, borderlayout.center);
    Aframe.setsize (300,200);
    Applet.init ();
    Applet.start ();
  Aframe.setvisible (TRUE); }
} ///:~

This separatesubtask name does not conflict with the separatesubtask in the previous precedent-even if they are in the same directory-because it has been hidden as an internal class. You can also see that the inner class is set to private (private), which means that its fields and methods have the default access rights (except run (), which must be set to public because it is exposed in the underlying class). No other aspect of the private inner class can be accessed except for Counter2i. And since two classes are tightly knit together, it's easy to relax the access restrictions between them. In Separatesubtask, we can see that the Invertflag () method has been deleted because Counter2i now has direct access to Runflag.
In addition, note that the Separatesubtask Builder has been simplified-it is now the only thing that starts the thread. The handle of the Counter2i object is still captured as it was before, but it is no longer achieved by passing and referencing external objects manually, at which point the internal class mechanism can take care of it automatically. In run (), you can see that access to T is done directly, as if it were a field of separatesubtask. The T field in the parent class can now become private, because separatesubtask can access it freely without any special permission-and, in any case, turn the field into a "private" property, in case some force from outside the class accidentally changes them.
Whenever you notice that the classes are tightly knit together, consider using internal classes to improve code writing and maintenance.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.