简体   繁体   中英

Updating Multiple Textbox Java GUI

I have an activity or form in which there is one text box called time here. As suggested by experts from this forum I am using runnable to update the TextBox while receiving the data from wifi.

My doubt is what to do when I want to update multiple TextBox's. Should I use multiple blocks of runnables like

              time1.post(new Runnable() {
                @Override
                public void run() {
                    time2.setText(s1);
                }
              });

             time2.post(new Runnable() {
                @Override
                public void run() {
                    time2.setText(s2);
                }
              });

            time3.post(new Runnable() {
                @Override
                public void run() {
                    time3.setText(s2);
                }
              });

Or some other technique is there to update multiple TextBoxes? My present code is like below.

package com.example.cdttiming;

public class MainActivity extends Activity
{
    EditText time;
    String s;
    Button button;
    byte[] buffer = new byte[65535];
    InetAddress ia = null;
     byte[] bmessage = new byte[1500];
     DatagramPacket dp = new DatagramPacket(bmessage, bmessage.length);
     MulticastSocket ms = null;
    @Override

    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

        time = (EditText) findViewById(R.id.et_time);
    try 
        {
        WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); 
        WifiManager.MulticastLock multicastLock = wm.createMulticastLock("multicastLock");
        multicastLock.setReferenceCounted(true);        
        multicastLock.acquire();      

        ia = InetAddress.getByName("226.1.1.1");    
        try {
            ms = new MulticastSocket(4321);
            } catch (IOException e) {
            e.printStackTrace();
            }
        try {
            ms.joinGroup(ia);
            } catch (IOException e) {
            e.printStackTrace();
            }

        ms.setReuseAddress(true);

        }
           catch (UnknownHostException e)               {
                time.setText(e.getMessage());

            }
            catch (IOException e)                {
                time.setText(e.getMessage());
             }     
     }

    public void startProgress(View view) {
        Runnable runnable = new Runnable() {
          @Override
          public void run() {              
        while(true)             {
             try                 {
                // String str="This is test string";
                  ms.receive(dp);
                  s = new String(dp.getData(),0,dp.getLength()); 
                  char retval[] = s.toCharArray();
             }
             catch (UnknownHostException e)                 {
                 time.setText(e.getMessage());

                }
               catch (IOException e)                    {
                   time.setText(e.getMessage());
                }     

            ****////// My doubt is here if i have multple strings of data and multiple
            /// multiple textboxes to update then what to do ???****

             time.post(new Runnable() {
                @Override
                public void run() {
                    time.setText(s);

                }
              });
           }  // while
          }
        };
        new Thread(runnable).start();
      }

    @Override
     public boolean onCreateOptionsMenu(Menu menu)      {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }   
}

I suggest you only create one runnable and post it once on main thread like this :

      time1.post(new Runnable() {
        @Override
        public void run() {
            time2.setText(s1);
            time2.setText(s2);
            time3.setText(s3);
        }
      });

The need to create a runnable and to post it on the main thread handler of a view is only about running a piece of code on the UI thread. No matter where you get the main thread handler reference from.

you could also have created your how handler on main thread :

protected void onCreate(Bundle savedInstanceState)
{
      this.uiThrdHandler = new Handler();
}

then post a runnable using it :

this.uiThrdHandler.post(new Runnable(){
        ...
});

Of course there is no need to create another handler but it's for demonstration purpose.

The Activity object has an utility method for that purpose : runOnUiThread

Using it, it would be :

  MainActivity.this.runOnUiThread (new Runnable() {
        @Override
        public void run() {
            time2.setText(s1);
            time2.setText(s2);
            time3.setText(s3);
        }
      });

But again, the result is the same.

Your code is a bit confusing. In one case inside your primary while loop you are capturing the data, assigning it to a String variable s then using the text widget post() function and a Runnable to set the EditText widget to that value. But inside that same while loop you have exception handlers that simply set the same EditText widget directly. Your code also looks like you could potentially lose messages if the while loop resets the value of s before the timer loop has a chance to fire the set text call.

It appears you are trying to create some form of real-time system and need the primary while loop to continually process, and display data as it becomes available. Now you have 3 different consumers (text widgets), but you didn't mention if you also have 3 different sources of messages or is there still only one main processing loop and some form of selector will decide which text widget gets the message?

Were I building something along these lines, I would probably use a messaging system and follow the producer-consumer model. When text was received, I would have the primary processing loop push a simple 2-field message onto a queue that contained a reference to the text widget and a reference to the data string. Because Strings are immutable in Java, once the message object had its own copy of the text, any changes to s would not affect the message.

Then, I would have a second thread running in the background that consumes the message queue. It would pull the message off the queue, construct a post call to the target text widget with the message data, fire it off, then go back to get the next message.

By going this route you separate the data processing thread from the UI update processing and would not need to worry about how many text widgets or other widgets you need updated. If you ever need to add others you only need to worry about the new widgets being known to the code that creates the update messages. The thread doing the widget update doesn't know how many widgets you have, it simply uses the one referenced in the update message object that the message creator said to use.

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