how to post the result of a running thread to a JtextArea (Java)
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
how to post the result of a running thread to a JtextArea (Java)
guys, I have a GUI that scan a range of ip address when press "scan" button; however, I'm having trouble displaying the result in the textArea box. I'm using a threads for my execution. here's the action performed when press the scan button. How could I get the output of the scan and put it into a textArea.setText(...);
Code:
IPrange netRange = new IPrange();
ArrayList<String> r = netRange.getRange();
public void StartIPscan() {
String ipFrom = ipTextFrom.getText();
String ipTo = ipTextTo.getText();
netRange.setFromip(ipFrom);
netRange.setToip(ipTo);
netRange.StrToIP();
netRange.calcNetwork();
/**
* ping sweep network
*/
Runnable scan = new IPscanner(r);
Thread t = new Thread(scan);
t.start();
}
here's the IPrange class that implements Runnable interface
Code:
import java.io.*;
import java.net.*;
import java.util.*;
public class IPscanner implements Runnable{
private String ipadd = "";
ArrayList<String> block;
public IPscanner(ArrayList r)
{
block = r;
}
public void run(){
boolean ping = false;
//ipadd = block.size()+"";
ipadd = "Scanning network "+"\""+block.get(0)+"...\""+"\n";
for(int i = 0; i < block.size(); i++)
{
try
{
int timeout = 1000;
InetAddress address = InetAddress.getByName(block.get(i));
//scanProgressBar.setValue(i);//updating progress bar
ping = address.isReachable(timeout);
if(ping == true)
{
ipadd += block.get(i)+" ---> is alive!"+"\n";
}
else
{
ipadd += block.get(i)+"\n";
}
}
catch(IOException e)
{
System.out.println(e);
}
}
}
public void setIPadd(String s)
{
ipadd = s;
}
public String getIPadd()
{
return ipadd;
}
}
guys, I have a GUI that scan a range of ip address when press "scan" button; however, I'm having trouble displaying the result in the textArea box. I'm using a threads for my execution. here's the action performed when press the scan button. How could I get the output of the scan and put it into a textArea.setText(...);
I see nothing in your code demonstrating how you are attempting to set the text. Did you forget to post the relevant code?
Is it your desire to post the results of all scans once the task is complete, or did you want to post intermediate results (sort of like a progress of completed pings)??
Here's a simple example demonstrating the use of JTextArea:
Code:
import javax.swing.*;
public class DisplayText extends JFrame
{
private JTextArea textArea = new JTextArea();
public DisplayText()
{
super("My Text Displayer");
add(textArea);
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void display()
{
setVisible(true);
}
public void showText(String text)
{
textArea.setText(text);
}
public static void main(String[] args)
{
DisplayText dt = new DisplayText();
dt.display();
String text = "";
for (int i = 0; i < 10; ++i)
{
text += i+1 + "\n";
dt.showText(text);
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
}
}
I see nothing in your code demonstrating how you are attempting to set the text. Did you forget to post the relevant code?
that is the problem... posting something to textArea is not difficult you get the return of your method and post it.... my problem is that I'm doing the scan implementing the run() method which is void(does not return anything). And the result is stored in "ipadd" and I have no way to access it.
Quote:
Is it your desire to post the results of all scans once the task is complete, or did you want to post intermediate results (sort of like a progress of completed pings)??
well, ideally it would be better to display as the scan is in progress, otherwise you would be sitting there wondering what's happening while the scan is in progress.
You would need to pass the handle to the JFrame object to IPScanner, so that IPScanner can, while is is performing the thread, update the JText area.
Here's an incomplete example:
Code:
public IPScanner implements Runnable
{
private String ipadd = "";
ArrayList<String> block;
MyFrame frame;
public IPscanner(ArrayList<String> r, MyFrame frame)
{
this.block = r;
this.frame = frame;
}
public void run()
{
boolean ping = false;
//ipadd = block.size()+"";
ipadd = "Scanning network "+"\""+block.get(0)+"...\""+"\n";
for(int i = 0; i < block.size(); i++)
{
try
{
int timeout = 1000;
InetAddress address = InetAddress.getByName(block.get(i));
//scanProgressBar.setValue(i);//updating progress bar
ping = address.isReachable(timeout);
if(ping == true)
{
ipadd += block.get(i)+" ---> is alive!"+"\n";
}
else
{
ipadd += block.get(i)+"\n";
}
// Update the frame with the ping status
frame.updateText(ipadd);
}
catch(IOException e)
{
System.out.println(e);
}
}
}
}
P.S. I see no reason for ipadd to be declared as a class member; it really only needs to be used locally within run().
P.S. #2 Make sure that the JTextArea, when updated within MyFrame's updateText() [or whatever you call it] is done in a thread-safe manner. For example:
Code:
public void updateText(final String text)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
myTextArea.setText(text);
}
});
}
Last edited by dwhitney67; 07-09-2012 at 12:02 PM.
You would need to pass the handle to the JFrame object to IPScanner, so that IPScanner can, while is is performing the thread, update the JText area.
Here's an incomplete example:
Code:
public IPScanner implements Runnable
{
private String ipadd = "";
ArrayList<String> block;
MyFrame frame;
public IPscanner(ArrayList<String> r, MyFrame frame)
{
this.block = r;
this.frame = frame;
}
public void run()
{
boolean ping = false;
//ipadd = block.size()+"";
ipadd = "Scanning network "+"\""+block.get(0)+"...\""+"\n";
for(int i = 0; i < block.size(); i++)
{
try
{
int timeout = 1000;
InetAddress address = InetAddress.getByName(block.get(i));
//scanProgressBar.setValue(i);//updating progress bar
ping = address.isReachable(timeout);
if(ping == true)
{
ipadd += block.get(i)+" ---> is alive!"+"\n";
}
else
{
ipadd += block.get(i)+"\n";
}
// Update the frame with the ping status
frame.updateText(ipadd);
}
catch(IOException e)
{
System.out.println(e);
}
}
}
}
when you mean a handle to a jframe you mean passing JTextArea as variable to the IPScanner class, then updating it from there? or a jFrame is different from JtextArea?
Quote:
P.S. I see no reason for ipadd to be declared as a class member; it really only needs to be used locally within run().
I agree!..
Quote:
P.S. #2 Make sure that the JTextArea, when updated within MyFrame's updateText() [or whatever you call it] is done in a thread-safe manner. For example:
Code:
public void updateText(final String text)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
myTextArea.setText(text);
}
});
}
this method would be part of my IPScanner class right?
when you mean a handle to a jframe you mean passing JTextArea as variable to the IPScanner class, then updating it from there? or a jFrame is different from JtextArea?
I would not pass the JTextArea object; keep that tucked away in your JFrame class. By reducing the exposure of the contents of a class, you will adhere to the notions of encapsulation. Your IPScanner should merely tell the JFrame object what text to display. If tomorrow, you decide to change the JTextArea to some other "widget", you would not need to change the IPScanner code.
I hope my response above answers your second question (hint: the updateText() method should be implemented within your JFrame class).
I would not pass the JTextArea object; keep that tucked away in your JFrame class. By reducing the exposure of the contents of a class, you will adhere to the notions of encapsulation. Your IPScanner should merely tell the JFrame object what text to display. If tomorrow, you decide to change the JTextArea to some other "widget", you would not need to change the IPScanner code.
I hope my response above answers your second question (hint: the updateText() method should be implemented within your JFrame class).
Ok, I think I got what you meant. Instead of passing the JTextArea(which I tried with same results) I created an Object of my JFrame and pass it with the constructor of IPScanner class; however, now I'm getting a runtime error
Code:
Exception in thread "Thread-2" java.lang.NullPointerException
at lanscan.IPscanner.run(IPscanner.java:49)
at java.lang.Thread.run(Thread.java:722)
and line 49 of IPScanner contains
Code:
myFrame.updateText(ipadd);
here's my code after I made the mods you suggested... thanks for the help
portions of my LanScanFrame class (JFrame)
Code:
IPrange netRange = new IPrange();
ArrayList<String> r = netRange.getRange();
LanScanFrame frame;
//performing ip scan
public void StartIPscan() {
String ipFrom = ipTextFrom.getText();
String ipTo = ipTextTo.getText();
netRange.setFromip(ipFrom);
netRange.setToip(ipTo);
netRange.StrToIP();
netRange.calcNetwork();
//ping sweep network
//Runnable scan = new IPscanner(r);
Thread t = new Thread(new IPscanner(r, frame));
t.start();
}
public void updateText(final String text)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ipOutputText.setText(text);
}
});
}
//clear ip range and ip output text area
public void clearIPrange()
{
ipTextFrom.setText("");
ipTextTo.setText("");
ipOutputText.setText("");
}
I do not see within your StartIPscan class where you are instantiating a LanScanFrame object. I see where you have declared the object (variable name is 'frame'), but no where is there a "new LanScanFrame()" statement. This may explain why 'frame' is null.
Btw, LanScanFrame should be defined to be something like the following; I notice that you have updateText() in StartIPscan... that's wrong:
Code:
public class LanScanFrame extends JFrame
{
...
public void updateText(final String text)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ipOutputText.setText(text);
}
});
}
}
Last edited by dwhitney67; 07-12-2012 at 04:54 PM.
I do not see within your StartIPscan class where you are instantiating a LanScanFrame object. I see where you have declared the object (variable name is 'frame'), but no where is there a "new LanScanFrame()" statement. This may explain why 'frame' is null.
Btw, LanScanFrame should be defined to be something like the following; I notice that you have updateText() in StartIPscan... that's wrong:
Code:
public class LanScanFrame extends JFrame
{
...
public void updateText(final String text)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ipOutputText.setText(text);
}
});
}
}
startIpscan is a method not a class... startIpscan and updateText are part of my LanScanFrame. I made some modification like constructing frame object in IPscanner class. take a look and see if it's correct
Code:
IPrange netRange = new IPrange();
ArrayList<String> r = netRange.getRange();
LanScanFrame frame;
//performing ip scan
public void StartIPscan() {
String ipFrom = ipTextFrom.getText();
String ipTo = ipTextTo.getText();
netRange.setFromip(ipFrom);
netRange.setToip(ipTo);
netRange.StrToIP();
netRange.calcNetwork();
//ping sweep network
//Runnable scan = new IPscanner(r);
Thread t = new Thread(new IPscanner(r, frame));
t.start();
}
public void updateText(final String text)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ipOutputText.setText(text);
}
});
}
IPscanner class
Code:
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import javax.swing.JTextArea;
public class IPscanner implements Runnable{
ArrayList<String> block;
LanScanFrame myFrame = new LanScanFrame();
public IPscanner(ArrayList r, LanScanFrame t)
{
block = r;
myFrame = t;
}
public void run(){
String ipadd;
boolean ping;
//ipadd = block.size()+"";
ipadd = "Scanning network "+"\""+block.get(0)+"...\""+"\n";
for(int i = 0; i < block.size(); i++)
{
try
{
int timeout = 2000;
InetAddress address = InetAddress.getByName(block.get(i));
//scanProgressBar.setValue(i);//updating progress bar
ping = address.isReachable(timeout);
if(ping == true)
{
ipadd += block.get(i)+" ---> is alive!"+"\n";
}
else
{
ipadd += block.get(i)+"\n";
}
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
myFrame.updateText(ipadd);
}
}
by the way when I start the scan I'm getting exceptions
Code:
Exception in thread "Thread-2" java.lang.NullPointerException
at lanscan.IPscanner.run(IPscanner.java:59)
at java.lang.Thread.run(Thread.java:722)
startIpscan is a method not a class... startIpscan and updateText are part of my LanScanFrame.
This would have been obvious had you posted all of your code; not just snip of it.
So, why do you declare a LanScanFrame object, 'frame', within the LanScanFrame class??
Quote:
Originally Posted by mia_tech
by the way when I start the scan I'm getting exceptions
Code:
Exception in thread "Thread-2" java.lang.NullPointerException
at lanscan.IPscanner.run(IPscanner.java:59)
at java.lang.Thread.run(Thread.java:722)
That is because you are still passing a null object to your thread. Now that you have revealed that LanScanFrame is the JFrame class that starts the thread, try something like:
Code:
public LanScanFrame extends JFrame
{
...
public void StartIPscan() {
...
Thread t = new Thread(new IPscanner(r, this));
t.start();
}
...
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.