Putting a return from a Callabe in a table
In my Callable
method in my class I am trying to accomplish the following:
1. Search In a File or Directory of Files for a keyword(s) concurrently (1 thread per directory)
2. If a file contains a match of the keyword within it, store the fileName, numberOfMatches, and fileSize in a String Array.
3. Update the JTable per result.
4. Method runs recursively.
Right now I'm trying to pass in a DefaultTableModel into the class which contains the search method.
public MatchCounter(File file, String keyword, Executor pool, DefaultTableModel outputTable);
and a Future Class to hold each String
Future<String[]> result;
now my problem is this, since my method runs recursively how can I provide a way to update my table per String[] and store it in?
is it possible to create a
Future<String[]>[] result;
?
I tried playing around with using String[][]
as the callable return but I ran into an ExecutorException.
PS: Yes i realize I don't have my code up, not at my office yet. Will post my code in about 5 hours. Thank you!
[1173 byte] By [
yidalia] at [2007-11-26 18:49:18]

# 1
Currently this is the call:
MatchCounter counter = new MatchCounter(pool, modelTable);
counter.addLocation(dirFile);
String keywordTemp = searchName.getText();
counter.addKeyword(keywordTemp);
result = pool.submit(counter);
try {
testInt = result.get();
//outputTable.notify();
}
catch (ExecutionException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null,"Execution Exception");
}
catch (InterruptedException e) {
JOptionPane.showMessageDialog(null,"Interrupted Exception");
}
this is the class and method
class MatchCounter implements Callable<Integer>
{
private File directory;
private String keyword;
private ExecutorService pool;
private DefaultTableModel modelTable;
private int count;
private int fileCount;
private String[] fileHolder;
/**
Constructs a MatchCounter.
@param directory the directory in which to start the search
@param keyword the keyword to look for
@param pool the thread pool for submitting subtasks
*/
public MatchCounter(ExecutorService pool, DefaultTableModel modelTable) {
this.pool = pool;
this.modelTable = modelTable;
}
public MatchCounter(File directory, String keyword, ExecutorService pool, DefaultTableModel modelTable){
this.directory = directory;
this.keyword = keyword;
this.pool = pool;
this.modelTable = modelTable;
}
public void addLocation(File directory) {
this.directory = directory;
}
public void addKeyword(String keyword) {
this.keyword = keyword;
}
public Integer call() {
count = 0;
try {
ArrayList<Future><Integer>> results = new ArrayList<Future><Integer>>();
if (directory.isDirectory()) {
File[] files = directory.listFiles();
for (File file : files)
if (file.isDirectory()) {
MatchCounter counter = new MatchCounter(file, keyword, pool, modelTable);
Future<Integer> result = pool.submit(counter);
results.add(result);
}
else {
if ( (fileCount = search(file)) > 0) {
fileHolder[0] = file.getName();
fileHolder[1] = Integer.toString(fileCount);
fileHolder[2] = Long.toString(file.length());
modelTable.addRow(fileHolder);
count++;
}
}
}
else {
if ( (fileCount = search(directory)) > 0) {
fileHolder[0] = directory.getName();
fileHolder[1] = Integer.toString(fileCount);
fileHolder[2] = Long.toString(directory.length());
modelTable.addRow(fileHolder);
count++;
}
}
for (Future<Integer> result : results)
try {
count = result.get();
}
catch (ExecutionException e) {
e.printStackTrace();
}
}
catch (InterruptedException e) {}
return count;
}
/**
Searches a file for a given keyword.
@param file the file to search
@return true if the keyword is contained in the file
*/
public int search(File file) {
try {
Scanner in = new Scanner(new FileInputStream(file));
int found = 0;
while (in.hasNextLine()) {
String line = in.nextLine();
if (line.contains(keyword))
found++;
}
in.close();
return found;
}
catch (IOException e){
return 0;
}
}
}
# 2
I fixed part of the problem, now it seems the return value is only the first Vector<String> instead of all results.
public Vector<String> call() {
count = 0;
try {
Vector<Future><Vector><String>>> results = new Vector<Future><Vector><String>>>();
fileHolder = new Vector<String>();
if (directory.isDirectory()) {
File[] files = directory.listFiles();
for (File file : files)
if (file.isDirectory()) {
MatchCounter counter = new MatchCounter(file, keyword, pool, modelTable);
Future<Vector><String>> result = pool.submit(counter);
results.add(result);
Thread.currentThread().sleep(0);
}
else {
if ( (fileCount = search(file)) > 0) {
System.out.println(file.getName() +" | " + fileCount + " matches | " + file.length() + " file size");
fileHolder.add(file.getName());
fileHolder.add(Integer.toString(fileCount));
fileHolder.add(Long.toString(file.length()));
// fileHolder[1] = Integer.toString(fileCount);
// fileHolder[2] = Long.toString(file.length());
//modelTable.addRow(fileHolder);
count++;
}
}
}
else {
if ( (fileCount = search(directory)) > 0) {
System.out.println(directory.getName() +" | " + fileCount + " matches | " + directory.length() + " file size");
fileHolder.add(directory.getName());
fileHolder.add(Integer.toString(fileCount));
fileHolder.add(Long.toString(directory.length()));
//fileHolder.add(directory.getName());
// fileHolder[1] = Integer.toString(fileCount);
// fileHolder[2] = Long.toString(directory.length());
//modelTable.addRow(fileHolder);
count++;
}
}
for (Future<Vector><String>> result : results)
try {
fileHolder = result.get();
}
catch (ExecutionException e) {
JOptionPane.showMessageDialog(null,"Execution Exception");
e.printStackTrace();
}
}
catch (InterruptedException e) {}
return fileHolder;
}
/**
Searches a file for a given keyword.
@param file the file to search
@return true if the keyword is contained in the file
*/
public int search(File file) {
try {
Scanner in = new Scanner(new FileInputStream(file));
int found = 0;
while (in.hasNextLine()) {
String line = in.nextLine();
if (line.contains(keyword))
found++;
}
in.close();
return found;
}
catch (IOException e){
return 0;
}
}
anyone have any clue on this? :o