In my application I have created one customized dialog box ,which is showed in both webview and normal android application,and also I doing some background operation when the dialog box is showed, when ever I called the mydialog function it shows my customized dialog box and also it return some values,it is perfectly working when I use webview+javainterface but it doesn't work with ordinary applications, the flow is
first I will get my dialog, after I do some process(here the main thread will wait ,dialog need to show,) then I will return the string ,the problem is dialog doesn't show when I called this function instead of that the dialog will showed after my background process finished.
I call this my dialog box like:
String sample=mydialog();
public String mydialog() {
String mystring = null;
try {
myactivity.this.runOnUiThread(ShowDialog);
while (customizeddialog.Getvalue() == null) {
}
mystring = customizeddialog.Getvalue();
customizeddialog.Setvalue(null);
} catch (Exception e) {
return mystring;
}
private Runnable ShowDialog = new Runnable() {
public void run() {
try {
customizeddialog m_dialog = new customizeddialog(myactivity.this);
m_dialog.setCancelable(false);
m_dialog.show();
} catch (Exception e) {
}
}
};
When you enter the synchronized block in mydialog() you acquire this's lock. Inside this synchronized block, you run ShowDialog() on the UI thread, and try to acquire this's lock again when you enter the synchronized block in ShowDialog.
Since the lock has already been acquired, it will wait until it is released in mydialog(), which will never happen because ShowDialog never executes past synchronized(this). What you have is deadlock.
Related
I am writing a simple text game and I've dacided to move from displaying
in cmd to displaying in a custom window, that constists of one TextArea used
for output and user input. So I need a method that waits for the String that
user writes and then returns it.
In Swing i would do something like this (in a Window class):
public String nextToken() {
synchronized (nextToken) {
while (nextToken.isEmpty())
try {
nextToken.wait();
} catch (InterruptedException e) {
print(e.getLocalizedMessage());
}
String tmp = nextToken.remove(0);
lastToken = text.getText();
newLine();
return tmp;
}
}
And the ActionListener for hitting enter:
public void actionPerformed(ActionEvent arg0) {
synchronized (nextToken) {
nextToken.add(text.getText().substring(lastToken.length(), text.getText().length()));
nextToken.notify();
} }; };
But when I create a Window using JavaFX and then try to use this method the window freezes.
What to do so that the window would display correctly and would wait for user input?
I'd be thankful for any advice
Sounds like you're waiting for input on the main thread, which will block it thus your window freezes. Try putting the waiting code (nextToken method) in a separate thread.
I have a button that starts a thread, which i use to show that my system is processing.
with thread1 i open a jdialog and to Show that my system is running. whereby i use thread2 to close my jdialog with dlg.dispose();
my problem is, once my program stops running, i click the button again, then an error message occurs, telling me that my thread has a problem.
I have another button without a thread behind and it performs the action perfectly if I click it another time.
Can somebody tell me where the problem is? I tried to close the thread by using Thread.currentThread().stop(); but it still does not work.
Here is my sample code,
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
if(chooser == null){
String message = "No file chosen. Please choose your file.";
JOptionPane.showMessageDialog(new JFrame(), message, "WiresharkHelper",
JOptionPane.ERROR_MESSAGE);
}
else if(chooser != null){
jTabbedPane4.setSelectedIndex(1);
thread1.start();
thread2.start();
}
}
JOptionPane opt = new JOptionPane("Application is running", JOptionPane.WARNING_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[]{});//I put this in global for my thread2 to dispose my dialog
JDialog dlg = opt.createDialog("Warning");
Thread thread2 = new Thread () {
public void run () {
dlg.setVisible(true);
}
};
Thread thread1 = new Thread () {
public void run () {
//code running
dlg.dispose();
}
};
Thread.currentThread().stop(); is #Deprecated JavaDoc
Try the following
Thread.currentThread().interrupt();
or
private volatile boolean stopRequested = false;
public void run() {
while (!stopRequested) {
...
}
}
public void requestStop() {
stopRequested = true;
}
My observations:
you are invoking Thread.currentThread().stop() on UI thread
itself, delete this line
thread2 is useless, delete it
invoke thread1 via SwingUtilities.invokeLater(thread1)
you are starting two threads and you have no way of saying, which will run first. I do not remember Swing that well now, but I would be surprised if first disposing dialog and then calling setVisible(true) would do something good
I am just not able to figure out the cause of this issue.
Problem :
1) I am using a Thread.Sleep function to set the timer for my application.
2) Now as soon as user enter the webPage the timer starts, if user clicks any link the timer(thread) is stopped and then new timer starts.
3) If their is no activity for say 3 seconds, timer ends and with it workflow associated with the webpage ends too.
Code :
DownloadSummariesPage.java
public DownloadSummariesPage(){
abc = new SimpleThread(this);
Link<Void> link = new Link<Void>("downloadSummaryLink") {
public void onClick() {
boolean threadStatus = abc.checkStatus();
if (threadStatus) {
abc.interrupt();
abc.stop();
abc = new SimpleThread(DownloadSummariesPage.this);
abc.start();
}
else
{
LOG.debug("thread is dead now");
endWorkflow();
LOG.debug("ending the workflow");
setResponsePage(MenuPage.class);
}
}
};
abc.start();
}
public void endWorkflow() {
abc.interrupt();
abc.stop();
boolean downloadReport = false;
LOG.debug("before action 201 inside endworkflow");
Map<String, Serializable> inputs = new HashMap<String, Serializable>();
inputs.put("downloadReport", downloadReport);
try {
wf.doAction(id, 201, inputs);//do not worry about this its for workflow
String empty = "";
populateDownloadReportDatabase(empty);
setResponsePage(MenuPage.class);
} catch (Exception e) {
LOG.debug("Exception while performing 201 workflow, getControlCancel "
+ e);
}
}
}
My next class which creates thread is
SimpleThread.java
class SimpleThread extends Thread {
private static final Logger LOG = Logger.getLogger(SimpleThread.class);
boolean stillActive = true;
DownloadSummariesPage dsp;
SimpleThread(DownloadSummariesPage dp) {
this.dsp = dp;
}
public void run() {
// 5sec timer
LOG.debug("inside run method");
try {
Thread.sleep(3000);
stillActive = false;
} catch (InterruptedException e) {
LOG.debug("Exception in thread " + e);
e.printStackTrace();
}
LOG.debug("before endworkflow");
dsp.endWorkflow();//so this is what i actually want to do...
LOG.debug("at the end of simplethread");
}
public boolean checkStatus() {
return stillActive;
}
}
Cases :
1) Whats Happening : User logs in thread sleeps, user click a link thread stops and creates a new one if user again click it happens again and now if user do not do anything for 3 seconds, stillAlive variable in SimpleThread class is set to false and when now user click its ends the workflow perfectly...
2) What i want : if user logs in thread starts, and if their is no activity by the user stillAlive variable is set to false and dsp.endWorkflow(); statement now should end the workflow. right ? but it just stops after reaching inside the endWorkflow() function and do not actually end the workflow...
Hope you get this, I tried my best to make it understandable. Thanks for your time..
I appreciate any help..
So there are some strange things here.
first assume the thread sleep without any interruption for 3 sec, so it will call the dsp.endWorkflow() where you call it again from the onClick method.
second the stillAlive flag should be volatile
boolean volatile stillActive = true;
The possible error/bug would raises by this section.
if (threadStatus) {
abc.interrupt();
abc.stop();// you cannot get to this like just after interrupt, maybe thread abc goes first
abc = new SimpleThread(DownloadSummariesPage.this);
abc.start();
}
because assume when thread is sleeping you interrupt it, then stop it, but this is possible that thread finishes it's work just after you interrupt it (before you stop it). so this is better to just stop it, or return when thread reached the catch.
try {
Thread.sleep(3000);
stillActive = false;
} catch (InterruptedException e) {
LOG.debug("Exception in thread " + e);
e.printStackTrace();
return;//////give up the rest work. so you don't need to call the stop too.
}
And the error is here
assume that user don't click the cancel, or new download, and thread just finishes its sleeping and call the dsp.endWorkflow(), so what is going on this method?
public void endWorkflow() {
abc.interrupt();
abc.stop();//error here!
boolean downloadReport = false;//this is unreachable
}
Just look, you are calling this method by abc thread, and the error is that you are killing the thread just inside the method, before you set the downloadReport to false. so it may would be like this.
public void endWorkflow() {
boolean downloadReport = false;//this is unreachable
abc.interrupt();
abc.stop();//error here!
}
I hope I could some help.
I tried this for many hours.. I have a thread that changes a JTextField of my UI, which completely destroys the UI. The Thread (lets call it Thread A) is generated by an ActionListener. The .setText() function call is in a extra thread (B) created by Thread A. Thread B is the Parameter of SwingUtilitis.invokeAll() and/or SwingUtilities.invokeAndWait(). I tried them both. Here's some code to make it more clear.
This is my ActionListener which creates Thread A - shortened of course:
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if (source == window.getBtn_Search()) {
Refresher refresh = new Refresher();
refresh.start();
}
}
This is my Thread A, which later puts Thread B into the EDT Queue:
public class Refresher extends Thread implements Runnable {
private int counter = 0;
private UI window = null;
private int defRefresh = 0;
#Override
public void run() {
while(true){
-bazillion lines of code-
do {
try {
Refresher.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(window.canceled()) break;
UI.updateCounter(window.getLbl_Status(), (Configuration.getRefreshTime()-counter));
counter++;
} while (counter <= Configuration.getRefreshTime());
- more code-
}
}
}
The UI.updateCounter(...) will queue Thread B into the EDT.
public static void updateCounter(final JLabel label, final int i) {
try {
SwingUtilities.invokeAndWait(
new Runnable() {
public void run() {
label.setText("Refreshing in: " + i + " seconds.");
}
}
);
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Now when the last function gets called, everything gets messed up. I tried different stuff for hours and nothing worked. I also tried using SwingWorker, but the some or nothing at all happened.
The invokeAndWait() tried allows to post a Runnable task to be executed on the EDT, but it blocks the current thread and waits until the EDT is done executing the task.
But there is deadlock potential in invokeAndWait(), as there is in any code that creates a thread interdependency.
If the calling code holds some lock (explicitly or implicitly) that the code called
through invokeAndWait() requires, then the EDT code will wait for the non-
EDT code to release the lock, which cannot happen because the non-EDT code
is waiting for the EDT code to complete, and the application will hang.
As we can see here, modifying the JLabel component passed by the waiting non-
EDT code.
Instead we can use
invokeLater() takes
care of creating and queuing a special event that contains the Runnable. This event is processed on the EDT in the order it was received, just like any other event.
When its time comes, it is dispatched by running the Runnable’s run() method.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
label.setText("Refreshing in: " + i + " seconds.");
}
});
OR
isEventDispatchThread() that returns true if the calling code is currently being executed on the EDT, false otherwise.
Runnable code= new Runnable() {
public void run() {
label.setText("Refreshing in: " + i + " seconds.");
}
}
);
if (SwingUtilities.isEventDispatchThread()) {
code.run();
} else {
SwingUtilities.invokeLater(code);
}
In general, labels are not very good at displaying text which change: their width change, and the layout with it.
Using a read-only JTextField, perhaps with proper changes in style, could be a better solution.
I think the intermediate JPanels you've created may count as validation roots. Therefore the revalidate() that automagically happens when you call setText() does not cause any layout changes higher than the level of the JPanel parent.
I don't think you actually need the panels, since a JLabel can contain both an Icon and text. See the tutorial.
So my advice is to remove the panels or, if they serve a purpose, make sure isValidateRoot() on the panels returns false.
When changing the label's text you should at least call repaint()/revalidate() on the label's topmost container, triggering a relayout, assuming the label calls invalidate()/revalidate() correctly on text change.
I have a program where I am loading a file while at the same time I am displaying a window to inform the user that the file is being loaded. I decided to make a FileLoader class that was a SwingWorker which actually handled loading the file and a ProgressWindow that implements PropertyChangeListener to inform the user about the status of the SwingWorker that was passed into it.
My code currently looks like this:
FileLoader loader = new FileLoader(filePath);
new ProgressWindow(loader, "Loading File", "Loading File");
//ProgressWindow's constructor calls loader.execute() inherited from SwingWorker
doc = loader.get(); //GUI Freezes when called
The problem is that whenever I call loader.get(), it freezes the GUI, thus the progress bar in the Progress Window doesn't run and the whole thing is pointless. As far as I can tell, this is because the thread controlling the GUI is the same thread that calls loader.get(), which goes on hold while loader.execute() is running.
So far, I've tried creating a new thread for either the loader.get() command or the loader.execute() method, and calling SwingUtilities.invokeLater() on the thread, but then the whole program freezes.
I've considered creating a ChangeListener for when SwingWorker.isDone() and then running loader.get(), but this would require some reworking of my code that I would rather not do.
Could anyone tell me what the best way is to get this to work?
get() is like join() in that it will block until called, and will wait for the SwingWorker to finish before being called. Using it wrongly can completely nullify all the advantages of using a SwingWorker in the first place.
Solution: Don't call get() until you know that the SwingWorker is done with its processing, by either calling it in the SwingWorker's done() method, or if you need to call it from the calling code, then in a PropertyChangeListener that has been added to the SwingWorker when the SwingWorker's "state" property is SwingWorker.StateValue.DONE.
Something like:
final FileLoader loader = new FileLoader(filePath);
loader.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())) {
// since DONE is enum, no need for equals(...) method
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
try {
loader.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
});
new ProgressWindow(loader, "Loading File", "Loading File");
Note: code not compiled nor tested
Edit: try/catch added.
So far, I've tried creating a new thread for either the loader.get() command or the loader.execute() method, and calling SwingUtilities.invokeLater() on the thread, but then the whole program freezes.
If you call SwingUtilities.invokeLater() on the thread that will execute the thread in the EDT which freezes the GUI. Instead, run the thread by calling it's start() method and only use SwingUtilities.invokeLater() when you need to update the progress bar in the PropertyChangeListener.
I have create a WorkerThread class which take care of Threads and GUI current/main thread .
i have put my GUI application in construct() method of WorkerThread when an event fire to start XXXServer then all threads are activate and GUI work smoothlly wihout freeze. have a look.
/**
* Action Event
*
* #see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent ae) {
log.info("actionPerformed begin..." + ae.getActionCommand());
try {
if (ae.getActionCommand().equals(btnStart.getText())) {
final int portNumber = 9990;
try {
WorkerThread workerThread = new WorkerThread(){
public Object construct(){
log.info("Initializing the Server GUI...");
// initializing the Server
try {
xxxServer = new XXXServer(portNumber);
xxxServer.start();
btnStart.setEnabled(false);
} catch (IOException e) {
// TODO Auto-generated catch block
log.info("actionPerformed() Start button ERROR IOEXCEPTION..." + e.getMessage());
e.printStackTrace();
}
return null;
}
};workerThread.start();
} catch (Exception e) {
log.info("actionPerformed() Start button ERROR..." + e.getMessage());
e.printStackTrace();
}
} else if (ae.getActionCommand().equals(btnStop.getText())) {
log.info("Exit..." + btnStop.getText());
closeWindow();
}
} catch (Exception e) {
log
.info("Error in ServerGUI actionPerformed==="
+ e.getMessage());
}
}