Updating JLabel with thread - java

I'm trying to get a thread to run for a swing application on button click, but the value isn't updating.
It supposed to grab the computer name I'm searching, but in order for the value to update I have to launch a new instance of the GUI.
I created a thread, but for some reason it's not working. Any help is appreciated.
(t.start is at end of code block)
searchComputerButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Thread t = new Thread("my non EDT thread") {
public void run() {
//my work
testLabel.setText(CN);
}
};
String line;
BufferedWriter bw = null;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(tempFile));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// String lineToRemove = "OU=Workstations";
String s = null;
Process p = null;
/*
* try { // p = Runtime.getRuntime().exec(
* "cmd /c start c:\\computerQuery.bat computerName"); } catch
* (IOException e1) { // TODO Auto-generated catch block
* e1.printStackTrace(); }
*/
try {
p = Runtime.getRuntime().exec("c:\\computerQuery.bat");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
StringBuffer sbuffer = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(p
.getInputStream()));
try {
while ((line = in.readLine()) != null) {
System.out.println(line);
// textArea.append(line);
String dn = "CN=FDCD111304,OU=Workstations,OU=SIM,OU=Accounts,DC=FL,DC=NET";
LdapName ldapName = new LdapName(dn);
String commonName = (String) ldapName.getRdn(
ldapName.size() - 1).getValue();
}
ComputerQuery.sendParam();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InvalidNameException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally
{
try {
fw.close();
}
catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
try {
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ComputerQuery.sendParam();
t.start();
}
});
UPDATE
private void threadStart() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
testLabel.setText(CN);
}
});
And I put the method here
JButton searchComputerButton = new JButton("Search");
searchComputerButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
threadStart();
String line;

Be aware of the Swing Thread https://docs.oracle.com/javase/tutorial/uiswin/concurrency/
Have a look here:
http://www.javamex.com/tutorials/threads/invokelater.shtml
You must enqueue your JLabel update method invocation using the Method
SwingUtilities.invokeLater(???).
Following example does it
Further more i think that is has something to do with the .batch file invocations. Have a look here: How do I run a batch file from my Java Application?
Runnable task = new UpdateJob("Query: " + i);
SwingUtilities.invokeLater(task);
To make it more understandable.
Swing manages all draw-Operations, within one Thread.
It provides a queue. If you call a method from outside of that queue the behaviour is completely unpredictable.. NullPointer... RuntimeExc....
But if you call SwingUtilities.invokeLater(...) your method will be enqueued into the Swing-Queue and invoked as soon as possible!
UPDATE due to comment:
check your mainthread (GUI)
check your threads.
when a sub-thread (e.g a ActionListener) want to call JLabel::setText
it has to use the method SwingUtils::InvokeLater("...");
That means invokeLater() has to be call within all threads which not directly belong to the main threads.
UPDATE due to Question
In my oppinion you current't code doesn't need SwingUtilities.invok.. at all.
Did you change the Code assigned to you your question.

Related

Retrieve results as single string each time a method is called in java

I want to retrieve the results of a method in a single string each time the function is called. I have a method which returns different results every time. I want to put all the results as a single string.
Tried to use append() method of java but the results are getting replaced every time as the function is called each time. but i need to retrieve the previous results as well.
my code is as follows.
public void createPanel2()
{
panel2 = new JPanel();
panel2.setLayout( new FlowLayout() );
query = new JLabel("query");
textbox =new JTextField(10);
submit = new JButton("submit");
panel2.add(query);
panel2.add(textbox);
panel2.add(submit);
submit.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
String str =textbox.getText();
String serverUrl = "http://localhost:8983/solr/collection1";
SolrServer solr = new HttpSolrServer(serverUrl);
try {
for (SolrDocument next : simpleSolrQuery(solr, str +
"")) {
prettyPrint(System.out, next);
}
} catch (SolrServerException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
initFilterAndButton();
}
SolrDocumentList simpleSolrQuery(SolrServer solr,
String query) throws SolrServerException {
SolrQuery solrQuery = new SolrQuery(query);
//SolrQuery query = new SolrQuery(searchTerm);
//query.setStart((pageNum - 1) * numItemsPerPage);
//query.setRows(numItemsPerPage);
//solrQuery.setRows(Integer.MAX_VALUE);
QueryResponse resp = solr.query(solrQuery);
//System.out.println("resp"+resp);
final SolrDocumentList hits = resp.getResults();
/*for (SolrDocument d : hits) {
for (Iterator<Map.Entry<String, Object>> i = d.iterator(); i
.hasNext();) {
Map.Entry<String, Object> e2 = i.next();
System.out.println(e2.getKey() + "\t" + e2.getValue());
}
System.out.println("------------------------");
}*/
System.out.println("hits"+resp.getElapsedTime());
System.out.println("size"+hits.size());
System.out.println("num found"+hits.getNumFound());
//String str ="hello";
//createPanel1(hits);
return hits;
}
void prettyPrint(PrintStream out, SolrDocument doc) {
List<String> sortedFieldNames =
new ArrayList<String>(doc.getFieldNames());
Collections.sort(sortedFieldNames);
out.println();
// StringBuilder contentstring=new StringBuilder();
// ArrayList<String> contents=new ArrayList<>();
for (String field : sortedFieldNames) {
if(field.equals("content")){
textarea.append(String.format("%s: %s",
field,doc.getFieldValue(field)+"\n"));
out.println(String.format("\t%s: %s",
field, doc.getFieldValue(field)));
contentsmethod(doc.getFieldValue(field).toString());
// contents.add(doc.getFieldValue(field).toString());
// System.out.println("conetnts"+contentstring);
}
}
// String test=contentstring.toString();
out.println();
}
public void contentsmethod(String fieldsvalues) {
// TODO Auto-generated method stub
StringBuilder contentstring=new StringBuilder();
contentstring.append(fieldsvalues);
try {
Desktop.getDesktop().browse(new URL(serverQuery+URLEncoder.encode(contentstring.toString())).toURI());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
The code above is calling the prettyPrint method every time and the results of that method should be retrieved to a single string which should hold the previous called results as well.
here i want to retrieve the results of contentstring.append(fieldsvalues);
But contentstring is returning only the current results and not appending the previous results.
this is obvious because the method is called everytime. Is there any work around to retrieve the previous results along with the current ones as well.
You need to move this StringBuilder contentstring=new StringBuilder(); outside of your method. Every time your method call is made, you create a new String. This is why you only get the current value.
You can make a List outside of your method and add the resulting String in that list. Otherwhise, you can create the string outside and append the results to it without instantiating a new one at every method call.
You have to do something like this:
StringBuilder contentstring = new StringBuilder();
public void contentsmethod(String fieldsvalues) {
// TODO Auto-generated method stub
contentstring.append(fieldsvalues);
try {
Desktop.getDesktop().browse(new URL(serverQuery+URLEncoder.encode(contentstring.toString())).toURI());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Are these Java Threads in dealock? [duplicate]

This question already has answers here:
Java InputStream blocking read
(7 answers)
Closed 8 years ago.
I have written a sample program to illustrate the working with pipe is thread. I have created 2 threads.
Thread1 is sending "Hi this is thread1" and call wait() for thread 2 to complete.
Thread2 is printing the message sent by thread1 and also will also append into a string buffer, then once the entire message is received, thread2 will print the contents of string buffer and will call notify. Now after calling wait() and notify both threads tend to be in deadlock
Strangely, thread2 prints the message one but does not print the contents of string buffer.
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
synchronized (obj)
{
obj.wait();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
OUTPUT::
Hello I am thread1
Updated Resolution:
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (obj)
{
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
Now i am a bit more confused. I just moved wait() from try catch to finally. How did it affect the blocking of Pipestream?
The problem is that
data = pipeinputstream.read();
in thread 2 is a blocking call. From the javadoc of PipedInputStream#read()
This method blocks until input data is available, the end of the
stream is detected, or an exception is thrown.
Thread 2 keeps waiting until one of those things happen. Since none of them will ever happen, the thread will not be able to notify the other.
This is not deadlock.
Note that even if that call unblocked and returned -1, thread 2 could still execute its notify before your thread 1 called wait. In which case, thread 1 would be a in a constant waiting state and your program would not terminate.

JProgressBar Doesn't Start Until Try-catch finishes

I am writing a program which uses Random.ORG api. When I click calculate button, JProgressBar starts right after the opeartion is being done and stay freezed until this moment.
I tried extra try-catch clauses, if statements and bool-gates. None of them worked, how could I fix it?
kazananiBelirleButon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
try {
HashMap<String, Object> randoms = randSonuc.generateSignedIntegers(5, 0, 10);
System.out.println(randoms.toString());
String test = randoms.toString().substring(randoms.toString().indexOf("{r")+1, randoms.toString().indexOf(", da")).replace("random=", "{\"random\":") + "}";
System.out.println(tarihiYazdir(test,14));
cekilisTarihiTextPane.setText(tarihiYazdir(test,2).toString());
sonucPane.setText("\n"+sonuclariYazdir(test,0));
} catch (RandomOrgSendTimeoutException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgKeyNotRunningError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientRequestsError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientBitsError e1) {
System.out.print("lol");
e1.printStackTrace();
} catch (RandomOrgBadHTTPResponseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgRANDOMORGError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgJSONRPCError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
Swing is single threaded. Calling listeners, painting/updating UI all happen on a single thread called the Event Dispatch Thread (EDT).
Since you do all your work in the event handler code, the Swing UI cannot be updated until you return from your method (actionPerformed()).
Read this tutorial: Concurrency in Swing
What you should do is do your time-consuming work in a separate thread and only do short tasks in the EDT (e.g. UI updates).
Also check out the SwingWorker class which is designed to perform lengthy GUI-interaction tasks in a background thread.
Try using swing worker in your method.
Swing Worker
Here is an example from old version of swing worker. Firs you need to add SwingWorker class to your project:
import javax.swing.SwingUtilities;
/**
* This is the 3rd version of SwingWorker (also known as
* SwingWorker 3), an abstract class that you subclass to
* perform GUI-related work in a dedicated thread. For
* instructions on using this class, see:
*
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
*
* Note that the API changed slightly in the 3rd version:
* You must now invoke start() on the SwingWorker after
* creating it.
*/
public abstract class SwingWorker
{
private Object value; // see getValue(), setValue()
private Thread thread;
/**
* Class to maintain reference to current worker thread
* under separate synchronization control.
*/
private static class ThreadVar
{
private Thread thread;
ThreadVar(Thread t)
{
thread = t;
}
synchronized Thread get()
{
return thread;
}
synchronized void clear()
{
thread = null;
}
}
private ThreadVar threadVar;
/**
* Get the value produced by the worker thread, or null if it
* hasn't been constructed yet.
*/
protected synchronized Object getValue()
{
return value;
}
/**
* Set the value produced by worker thread
*/
private synchronized void setValue(Object x)
{
value = x;
}
/**
* Compute the value to be returned by the <code>get</code> method.
*/
public abstract Object construct();
/**
* Called on the event dispatching thread (not on the worker thread)
* after the <code>construct</code> method has returned.
*/
public void finished()
{
}
/**
* A new method that interrupts the worker thread. Call this method
* to force the worker to stop what it's doing.
*/
public void interrupt()
{
Thread t = threadVar.get();
if (t != null)
{
t.interrupt();
}
threadVar.clear();
}
/**
* Return the value created by the <code>construct</code> method.
* Returns null if either the constructing thread or the current
* thread was interrupted before a value was produced.
*
* #return the value created by the <code>construct</code> method
*/
public Object get()
{
while (true)
{
Thread t = threadVar.get();
if (t == null)
{
return getValue();
}
try
{
t.join();
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt(); // propagate
return null;
}
}
}
/**
* Start a thread that will call the <code>construct</code> method
* and then exit.
*/
public SwingWorker()
{
final Runnable doFinished = new Runnable()
{
public void run()
{
finished();
}
};
Runnable doConstruct = new Runnable()
{
public void run()
{
try
{
setValue(construct());
}
finally
{
threadVar.clear();
}
SwingUtilities.invokeLater(doFinished);
}
};
Thread t = new Thread(doConstruct);
threadVar = new ThreadVar(t);
}
/**
* Start the worker thread.
*/
public void start()
{
Thread t = threadVar.get();
if (t != null)
{
t.start();
}
}
}
Then add your logic inside:
SwingWorker worker = new SwingWorker() {
#Override
public Object construct() {
// add your code here
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
// and so on...
return 0;
}
};
worker.start();
So the end resuld should look like this (Note that this is untested code):
kazananiBelirleButon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SwingWorker worker = new SwingWorker() {
#Override
public Object construct() {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
try {
HashMap<String, Object> randoms = randSonuc.generateSignedIntegers(5, 0, 10);
System.out.println(randoms.toString());
String test = randoms.toString().substring(randoms.toString().indexOf("{r")+1, randoms.toString().indexOf(", da")).replace("random=", "{\"random\":") + "}";
System.out.println(tarihiYazdir(test,14));
cekilisTarihiTextPane.setText(tarihiYazdir(test,2).toString());
sonucPane.setText("\n"+sonuclariYazdir(test,0));
} catch (RandomOrgSendTimeoutException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgKeyNotRunningError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientRequestsError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientBitsError e1) {
System.out.print("lol");
e1.printStackTrace();
} catch (RandomOrgBadHTTPResponseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgRANDOMORGError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgJSONRPCError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return 0;
}
};
worker.start();
});

Execute multiple tasks on async task or in async task, and return data from postexecute

I have an API that I use to retrieve daily schedules on the live cable-tv for various channels. I have a scenario in which I need a guidance as to which approach should work here.
Lets say I need schedules for 10 different channels from the API.
Should I execute 10 different async tasks for the retrieval of the required data?
Problem:
How would I collect the data in an arraylist and return it once all execution is completed?
How will I access the arraylist in my main function once onpostexecute returns the result?
Or I should just provide the list of channels to my single async task and make it build a single output of arraylist for my main function invoking it?
Problem:
Since I will be accessing a webservice for this purpose, will it make it run slow as compared to my 1st approach?
Second problem with this approach is the same as I am having with my 1st one, I need to know when and how to get the complete resultset once the execution of the task is completed?
Here is some code to explain the problem:
//going with the first approach
//invoking my asynctask from an activity or another class
//I need a global arraylist which I can use after postexecute returns its result
ArrayList<String> channels = channelManager.getAllChannelsByRegion("xyz");
final ArrayList<ChannelSchedule> schedules = new ArrayList<ChannelSchedule>();
final ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
for (int i = 0; i < channels.size(); ++i){
AsyncInvokeURLTask task = null;
try {
task = new AsyncInvokeURLTask(
channels.get(i), context, new AsyncInvokeURLTask.OnPostExecuteListener() {
#Override
public void onPostExecute(String result) {
// TODO Auto-generated method stub
try {
//Need to add results to arraylist here...But cannot know when it ends completely
ChannelSchedule schedule = mapper.readValue(result, ChannelSchedule.class);
Log.v("channel name", schedule.getChannelName());
Log.v("channel date", schedule.getDate());
Log.v("channel thumb", schedule.getListOfShows().get(0).getShowThumb());
Log.v("channel time", schedule.getListOfShows().get(0).getShowTime());
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.execute();
}
Please let me know if something is not clear or missing.
Launching 10 AsyncTask is perfectly fine.
You can keep a count of the number of pending requests. As OnPostExecute is run on the UI thread there are no risks of race condition.
private int numberOfPendingRequests;
public void MyFunc() {
ArrayList<String> channels = channelManager.getAllChannelsByRegion("xyz");
final ArrayList<ChannelSchedule> schedules = new ArrayList<ChannelSchedule>();
final ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
numberOfPendingRequests = channels.size();
for (int i = 0; i < channels.size(); ++i) {
schedules.add(null);
}
for (int i = 0; i < channels.size(); ++i) {
AsyncInvokeURLTask task = null;
final int index = i; // final so it can be used in the onPostExecute.
try {
task = new AsyncInvokeURLTask(
channels.get(i), context, new AsyncInvokeURLTask.OnPostExecuteListener() {
#Override public void onPostExecute(String result) {
try {
ChannelSchedule schedule = mapper.readValue(result, ChannelSchedule.class);
Log.v("channel name", schedule.getChannelName());
Log.v("channel date", schedule.getDate());
Log.v("channel thumb", schedule.getListOfShows().get(0).getShowThumb());
Log.v("channel time", schedule.getListOfShows().get(0).getShowTime());
schedules.set(index, schedule);
numberOfPendingRequests--;
if (numberOfPendingRequests == 0) {
// Everything is received, do stuff here.
}
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.execute();
}
}

How to prevent JFrame from closing

I have a Java GUI application from which another java GUI application is invoked using reflection and loading. It works fine the only problem faced is, on closing the JFrame of invoked application the Main GUI application frame also closes. How can I prevent the main application (frame) from closing??
I cannot change the defaultCloseOperation of the invoked application, However a change to the main application can be made. Does it have any thing to do with threads??
This is my applications code that executes a target application
public class ClassExecutor{
private ClassLoaderOfExtClass classLoader;
private byte[][] ArrayOfClasses;
private String[] ArrayOfBinaryNames;
#SuppressWarnings("rawtypes")
private ArrayList<Class> loadedClasses;
private ArrayList<String> loadedClasesNames;
private Object[] parameters;
#SuppressWarnings("rawtypes")
public ClassExecutor() {
classLoader = new ClassLoaderOfExtClass();
new ArrayList<Class>();
loadedClasses = new ArrayList<Class>();
loadedClasesNames = new ArrayList<String>();
}
#SuppressWarnings("unchecked")
public void execute(File[] file, String[] binaryPaths) {
Object[] actuals = { new String[] { "" } };
Method m = null;
try {
Field classesx=ClassLoaderOfExtClass.class.getDeclaredField("classes");
classesx.setAccessible(true);
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (NoSuchFieldException e1) {
e1.printStackTrace();
}
/*for (int i = 0; i < file.length; i++) {
for (int j = 0; j < file.length; j++) {
try {
#SuppressWarnings("rawtypes")
Class c = classLoader.loadClassCustom(file[i], binaryPaths[i]);
//Fied classex=classLoader.getResource("classes");
}catch(Exception e){
}
}
}
Class<?>[]classesxx= getLoadedClasses(classLoader);
System.out.println("Loaded classes have size "+ classesxx.length);*/
for (int i = 0; i < file.length; i++) {
try {
#SuppressWarnings("rawtypes")
Class c = classLoader.loadClassCustom(file[i], binaryPaths[i]);
try {
if (c.getMethod("main", new Class[] { String[].class }) != null) {
m = c.getMethod("main", new Class[] { String[].class });
} else {
System.out.println("This class does not contain main");
continue;
}
} catch (NoSuchMethodException e) {
// System.out.println("Main not found!!!");
// System.out.println("M here");
// e.printStackTrace(); // not printing stack trace
} catch (SecurityException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
System.out.println("No such class definition exist!!");
// TODO Auto-generated catch block
// e.printStackTrace();
}
}
try {
m.invoke(null, actuals);
// CallStack.print();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public void execute(ArrayList<byte[]> stuffedFiles,
ArrayList<String> binaryPaths) {
convertToArray(stuffedFiles, binaryPaths);
loadAllClasses(ArrayOfClasses, ArrayOfBinaryNames);
Object[] actuals = { new String[] { "" } };
Method m = null;
/*
* Method[] m1= new Method[10]; for (Class c : loadedClasses) {
* m1=c.getMethods(); } for(Method m2: m1){
* System.out.println(m2.getName()); }
*/
/* System.out.println(loadedClasses.size()); */
for (Class c : loadedClasses) {
/*
* System.out.println(c.toString());
* System.out.println(c.getConstructors());
*/
// for (int i = 1; i < file.size(); i++) {
/*
* for(Method meth : c.getMethods()){ meth.setAccessible(true);
*
* }
*/
try {
if (c.getMethod("main", new Class[] { String[].class }) != null) {
m = c.getMethod("main", new Class[] { String[].class });
break;
} else {
// System.out.println("This class does not contain main");
continue;
}
} catch (NoSuchMethodException e) {
System.out.println("Program does not contain main");
} catch (SecurityException e) {
e.printStackTrace();
}
}
try {
if(parameters==null){
m.invoke(null, actuals);
}
else{
try {
System.out.println("It Fails Here");
m.invoke(null, parameters);
} catch (Exception e) {
System.out.println("Illegal arguments");
}
}
// CallStack.print();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You'll want to use the DISPOSE_ON_CLOSE operation, so it would be setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
EXIT_ON_CLOSE would be the option that closes all windows which I believe is what you are currently experiencing.
You have the following options for the defaultCloseOperation:
DO_NOTHING_ON_CLOSE - The do-nothing default window close operation;
HIDE_ON_CLOSE - The hide-window default window close operation;
DISPOSE_ON_CLOSE - The dispose-window default window close operation.
EXIT_ON_CLOSE - The exit application default window close operation. Attempting to set this on Windows that support this, such as JFrame, may throw a SecurityException based on the SecurityManager. It is recommended you only use this in an application.
The Option DISPOSE_ON_CLOSE could be used in order to avoid to close all windows, closing just the one you want.
If you don't have direct access to JFrame object as you have with the last posted code, you could use Window.getWindows() in order to receive all windows instance (as JFrame is a Window too it will be listed too). And then set the defaultCloseOperation on that.
Possibly you will need to use threads because the defaultCloseOperation needs to be set after invoke main method.
Theoretically it works, so I think this is a good shot ;)
I am not allowed to make changes to the application being invoked.
That was a comment in reply to #JeffLaJoie just to clarify, it would not require any changes to the code of the other app., just an extra method call or two by your app. at run-time to set the close operation of the 3rd party frame.
Failing that, the best solution I can think of is to start the new frame in a separate Process that starts a new JVM, when the user closes the other app., it and the 2nd JVM will end, while leaving the original app. on-screen.

Categories

Resources