Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 01-13-2009, 12:39 AM
Member
 
Join Date: Jan 2009
Posts: 4
Rep Power: 0
enigmaymee is on a distinguished road
Default Big time NOOB
I have some coding experiance but I'm extremely new to java. I started reading tutorials a few days ago and today I started trying some things out. I'm sure I'm missing something really simple here.

OK. so for my 1st program I decided to write a ping program. It's a GUI with 2 text fields and a button. Type the ip in the 1st field, press button and it gives output in second field.

The problem I have is that I wanted it to say it was working while it is waiting for the dead ips to fail. But the line where it prints "Working..." in the second field doesn't work and I can't figure out why.

Any ideas?

Code:
public void pingCmd() {
        try {
            jTextField2.setText("Working...");
            boolean status = InetAddress.getByName(jTextField1.getText()).isReachable(3000);
            if (status == true) {
                jTextField2.setText("Alive");
            } else {
                jTextField2.setText("Dead");
            }
        } catch (IOException ex) {
            Logger.getLogger(NewJDialog.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        pingCmd();
    }
BTW, this is just part of the program. I'm using netbeans as my IDE and it of course adds a lot of other stuff to create the window and stuff so that part is not included.
Bookmark Post in Technorati
Reply With Quote
  #2 (permalink)  
Old 01-13-2009, 03:07 AM
Eku Eku is offline
Senior Member
 
Join Date: May 2008
Location: Makati, Philippines
Posts: 234
Rep Power: 2
Eku is on a distinguished road
Default
can put a stacktrace pls ^_^
__________________
Mind only knows what lies near the heart, it alone sees the depth of the soul.
Bookmark Post in Technorati
Reply With Quote
  #3 (permalink)  
Old 01-13-2009, 03:47 AM
Member
 
Join Date: Jan 2009
Posts: 4
Rep Power: 0
enigmaymee is on a distinguished road
Default
Well, I'm not sure how to do a stack trace with netbeans or java but I'm not sure if a trace would show anything. The app doesn't crash and I've found that the line does actually work but not in the way I intended.

If I comment the other two setText commands then it does print "Working..." but only after the isReachable times out. And since the other two setText commands are also printed after it times out then it is overwritten so fast you can't see it.

The 1st line in the main method is:
Code:
java.awt.EventQueue.invokeLater(new Runnable() {
which from what I've read doesn't appear to be the culprit(unless I'm misunderstanding it).

Any other ideas? Or can someone point me in the right direction for doing the stack trace?

Thanks for your help BTW.
Bookmark Post in Technorati
Reply With Quote
  #4 (permalink)  
Old 01-14-2009, 04:36 PM
Member
 
Join Date: Jan 2009
Posts: 4
Rep Power: 0
enigmaymee is on a distinguished road
Default
I found the solution to my problem! Woot!

Ok, sorry. Anyway I'll post it here in case anyone else is a huge java noob like me and didn't know this info.

With swing apps when you have some code that is going to take a while (like 2 seconds for something to timeout) and you run the code in the same thread (which is called the event dispatch thread) then your gui will not update.

so here is how I changed that program to use a worker thread:

Code:
    private void pingCmd() {
       SwingWorker worker = new SwingWorker() {
            @Override
            protected Object doInBackground() throws Exception {
                jTextField2.setText("Working...");
                boolean status = InetAddress.getByName(jTextField1.getText()).isReachable(3000);
                if (status == true) {
                    jTextField2.setText("Alive");
                } else {
                    jTextField2.setText("Dead");
                }
                 return status;
            }
        };
        worker.execute();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        pingCmd();
    }
And now my gui doesn't freeze while it's waiting for the ping to time out. I'm sure it's not the best implementation of SwingWorker or any of the other code either, but it is my 1st real java app and I'm still learning.
Bookmark Post in Technorati
Reply With Quote
  #5 (permalink)  
Old 01-14-2009, 04:56 PM
Fubarable's Avatar
Moderator
 
Join Date: Jun 2008
Posts: 6,483
Rep Power: 8
Fubarable is on a distinguished road
Default
Quote:
so here is how I changed that program to use a worker thread:
You are on the right track here by performing long actions in a background thread so as not to tie up the Swing Event Dispatch Thread (EDT), but you must take care when doing this that you don't inadvertently cause thread violations. These violations cause some pernicious errors that only happen every now and then, but are a witch to debug.

For instance, you need to realize that code run in the doInBackground method is done off of the EDT, and so you shouldn't make Swing calls from within this method without proper precautions. By Swing calls here I mean reading from and especially writing to the JTextFields. Another way to do what you want is to use the done() method to do your writing to text fields and a constructor to do the reading:

Code:
public class Fubar
{
  private JTextField jTextField1 = new JTextField(10);
  private JTextField jTextField2 = new JTextField(10);

  private void pingCmd()
  {
    jTextField2.setText("Working...");
    
    // pass the jtextfield text in a thread-safe way
    Worker worker = new Worker(jTextField1.getText());
    worker.execute();
  }

  private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
  {
    pingCmd();
  }

  private class Worker extends SwingWorker<Boolean, Void> 
  {
    private String addressString;
    
    Worker(String addressString)
    {
      this.addressString = addressString;
    }
    @Override
    // this is not called on the EDT
    protected Boolean doInBackground() throws UnknownHostException, IOException 
    {
      boolean status = InetAddress.getByName(addressString).isReachable(3000);
      return status;
    }

    @Override
    protected void done() // this is called on the EDT
    {
      try
      {
        if (get()) // get gets what is returned from the doInBackground method, a Boolean
        {
          jTextField2.setText("Alive");
        }
        else
        {
          jTextField2.setText("Dead");
        }
      }
      catch (InterruptedException e)
      {
        e.printStackTrace();
      }
      catch (ExecutionException e)
      {
        e.printStackTrace();
      }
    }
  }
}
Quote:
but it is my 1st real java app and I'm still learning.
Yeow, you don't start "small" do you? LOL, well, best of luck.
Bookmark Post in Technorati
Reply With Quote
  #6 (permalink)  
Old 01-14-2009, 06:49 PM
Member
 
Join Date: Jan 2009
Posts: 4
Rep Power: 0
enigmaymee is on a distinguished road
Default
Thank you very much. That info is very useful.

I didn't think about possible problems coming from writing to text fields in the worker thread. But now I can definitely see the reasoning for doing it that way.
Bookmark Post in Technorati
Reply With Quote
  #7 (permalink)  
Old 01-14-2009, 06:56 PM
Fubarable's Avatar
Moderator
 
Join Date: Jun 2008
Posts: 6,483
Rep Power: 8
Fubarable is on a distinguished road
Default
Originally Posted by enigmaymee View Post
Thank you very much. That info is very useful.
You're welcome.
Quote:
I didn't think about possible problems coming from writing to text fields in the worker thread. But now I can definitely see the reasoning for doing it that way.
I didn't either, but a while back I looked at the source code for this, and it's a lot more involved than I had thought and carries with it a significant risk for thread violations.
Bookmark Post in Technorati
Reply With Quote
  #8 (permalink)  
Old 01-14-2009, 07:11 PM
Steve11235's Avatar
Senior Member
 
Join Date: Dec 2008
Posts: 972
Rep Power: 2
Steve11235 is on a distinguished road
Default
You were right to create a worker thread; SwingWorker is overkill unless you use its capabilities.

Fubar is correct in saying that you should not update the GUI from a worker thread.

Here is a way to correct your new code without rewriting it. This looks ugly, but it is the standard. You can cut and paste it (or type it from memory)
Code:
EventQueue.invokeLater(new Runnable() {
  @Override
  public void run() {
    // update your GUI here
  }
});
Your code runs of the event dispatch thread (the Swing thread) after it finishes any previous requests.
Bookmark Post in Technorati
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Noob nokomis Introductions 2 03-06-2009 06:10 PM
Hello, Java Noob furry Introductions 0 10-07-2008 08:39 PM
Please help a noob :) Bays New To Java 15 06-17-2008 07:11 AM
[noob]Problem with TOS .bat fred33 Advanced Java 0 03-19-2008 03:04 PM
Ah! Help a Java Noob Snejana New To Java 4 01-24-2008 04:52 AM


All times are GMT +2. The time now is 03:41 PM.



VBulletin, Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2009, Crawlability, Inc.
Copyright ©2006 - 2007, www.java-forums.org