I am creating a matching game for Android, and when the user gets a match, a dialog box should pop up saying "Match!" I cannot figure out how to do this though. If I use Thread.currentthread().sleep, the dialog never appears.
android.app.AlertDialog a = new android.app.AlertDialog.Builder(match.this).setTitle("Match!").show();
Thread.currentthread().sleep(1000);
a.dismiss();
Nothing happens - the program just hangs for a second. I would like it to pop up for just 1 second, or if there is another sort of popup type thing, that would be good too.
You're trying to show a text message in a popup for a short period of time on the screen?
For these kind of alerts toasts are great:
Toast.makeText(this, "Match!", Toast.LENGTH_LONG).show();
Is that what you are looking for?
Here is the Java Doc.
The dialog is shown in the current thread but you are putting the thread to sleep so it never shows up. Other than event throttling, there are few cases where you want to call sleep with a substantial delay from the UI thread.
In this case using a Toast is easiest as the previous poster suggested. A couple of other ways to handle work you want done in the future
Java Timers. The action will happen
on a different thread so you have to
be carefull what gui calls you make
Views have a postDelayed(Runnable action, long delayMillis) method will cause the Runnable to be executed on the UI thread after roughly delayMillis.
Related
I have a question about the Android Studio:
I have an Image view. Let's call it ImageView. I call the method setOnCLickListener on this ImageView with a listener new View.OnclickListener().
In the method onClick() of this listener, I change an attribute (the color, the image itself...) of this imageView. For example, I change the image with imageView.setImageResource(R.drawable.new_image). I then wait for 10 sec with Thread.sleep(10000). I then set back the previous image with imageView.setImageResource(R.drawable.previous_image).
Here is my question:
I expect the ImageView to change its image for 10 sec and then have the previous image back. However, I see no change on this ImageView. I only see the first image...Could someone explain me why?
I hope I was clear enough...Thank you in advance for your help :) !!
R.id.drawable.previous_image ?. It should be R.drawable.previous_image
First of all, you should read the Processes and Threads guide to understand how threading works on Android.
If you're done with with that, you'll understand that what you do is really bad because you freeze the main (UI) thread which means the application will not respond to any events until the 10 seconds pass. This also results in an ANR (Application Not Responding) dialog which is pretty bad UX.
You basically need to delegate the waiting period to another thread (or a queue at least), then when the time comes, go back to the UI thread and set whatever view attribute you want. There are many ways to achieve this, you should read Communicating with the UI Thread for more details. Here's just a quick sample:
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
// write here what you want to happen in 10 seconds on the UI thread
}
}, 10000); // 10s = 10,000ms
Here are some notes though:
Save the Runnable you create here to a variable because if the user navigates away from this screen within the 10 seconds, it will still run the code inside, which might result in various exceptions. In this case you need to remove that Runnable from the handler by calling handler.removeCallbacks(runnable); when the user leaves the screen.
Don't create a new Handler instance every time the click event happens. Create it in the Activity's onCreate(...) method and use that instance in the rest of the screen.
You could create the Handler without the Looper parameter, which would create the handler for the current thread's Looper and that would be fine now since it's being created on the UI thread. However, I decided it's better to show you the safer way since you might end up doing something similar on a background thread that could result in unexpected behavior if you don't understand the threading yet.
I am working on an application that will have the following feature:
The application will have a "Load Image" button to open an image and settings modal dialog. It will need to block until that dialog returns, either with the results of the processing or null if the user changed his mind.
The image and settings dialog will allow the user to select an image using a JFileChooser dialog and to specify to what level of detail to process the image. Clicking a "Load" button will open a load dialog.
The load dialog needs to be a custom-designed dialog that reports in detail about the time-consuming processing of the image. If the user allows the processing to finish, it needs to close and return the object back to the original dialog, which needs to close and return that object back to the application. If the user decides it is taking too long to perform the processing, he can cancel the load, closing the loading dialog and returning to the image and settings dialog.
Conceptually, this does not seem so difficult to me. However, when I try to determine how to get this to work within Swing, somehow I cannot put it together. From what I've read, GUI components need to be instantiated in Swing's event thread since many of them are not thread-safe. These same components need to block on calls similar to (but not the same as, since I need to write custom components) the JOptionPane.showInputDialog() methods. But these calls need to instantiate new components in the event thread and wait for events to occur in the event thread before returning a value to the application. Compounding this with the fact that I need a dialog to pop up from a dialog, I feel quite lost.
I have read the Java Tutorial on dialogs and several posts on StackOverflow and other sites trying to determine how I can design classes that work correctly. Somehow, I just don't understand how this can work at all (isn't the event thread going to sleep after the first blocking call?), and how I can write the custom classes I need to make this work. Frankly, I am not certain I understand my confusion enough that I was able to explain it.
Could someone please explain what goes on under the hood when modal dialogs have been instantiated? How I can write dialog classes that behave the way I need as described above?
The application will have a "Load Image" button to open an image and settings modal dialog. It will need to block until that dialog returns, either with the results of the processing or null if the user changed his mind.
OK, so this dialog will need to be modal. That much we know.
The image and settings dialog will allow the user to select an image using a JFileChooser dialog and to specify to what level of detail to process the image. Clicking a "Load" button will open a load dialog.
OK, so the load dialog will need to be modal off of the image and settings dialog. No biggie there either.
The load dialog needs to be a custom-designed dialog that reports in detail about the time-consuming processing of the image. If the user allows the processing to finish, it needs to close and return the object back to the original dialog, which needs to close and return that object back to the application. If the user decides it is taking too long to perform the processing, he can cancel the load, closing the loading dialog and returning to the image and settings dialog.
OK, so the load dialog code will need to instantiate and execute a SwingWorker to do the time-consuming image processing in a background thread, and then have the SwingWorker use its publish/process method pair to push information about the processing details back to the load dialog.
...From what I've read, GUI components need to be instantiated in Swing's event thread since many of them are not thread-safe.
Correct.
These same components need to block on calls similar to (but not the same as, since I need to write custom components) the JOptionPane.showInputDialog() methods.
And this is what a modal JDialog allows you to do. Another option to keep in mind is to use a JOptionPane and pass in a JPanel with whatever GUI you want the JOptionPane to display. JOptionPanes are surprisingly flexible and useful.
But these calls need to instantiate new components in the event thread and wait for events to occur in the event thread before returning a value to the application. Compounding this with the fact that I need a dialog to pop up from a dialog, I feel quite lost.
Again it's simple. The load dialog will call a SwingWorker which will communicate back to the load dialog.
Could someone please explain what goes on under the hood when modal dialogs have been instantiated?
Now you may be asking a bit too much for the volunteers on this site to do, since this question would probably require someone to write a complete tutorial to answer, and it has been asked and answered before, so the information should be discoverable by you. If you really want to see what is going on under the hood, you should first do the preliminary research on the subject yourself, look at the source code, and if still stuck, ask a much more specific and answerable question after first doing your own due diligence work.
Modal dialogs started from the primary event loop spawn a secondary event loop that remains active while the primary loop is blocked. See java.awt.SecondaryLoop.
I've got a button that kicks off a background thread to do some work and I am trying to use a ProgressDialog to prevent the user from double clicking that button (or any other ui elements) while that work is being done. The first thing I do in my buttons onClick code is to display the progress dialog, which takes over the screen. The problem I am seeing is that if I rapidly tap this button, sometimes two or more presses will register before the ProgressDialog is shown. This leads me to assume that ProgressDialog.show() is returning before the ProgressDialog is actually visible.
Can anybody confirm this? Also, is there a way to change this behavior, or at least get a notification of when the dialog is actually visible? I saw Dialog.onStart() but given the javadoc, this appears to be called before the Dialog is actually visible...
UPDATE:
While it appears that there is no good way of solving this problem in general, the following works for my situation where my work is done by an external thread and the amount of work to do takes longer than the time it takes for all the button clicks to be processed:
void myOnClickHandler() {
if(myButton.isEnabled()) {
myButton.setEnabled(False);
// do work here
// setEnabled(true) is invoked at the end of my spawned thread's run().
}
}
No.
The problem is you clicked many times before the click event is delivered. (i.e. it is queued before you run ProgressDialog.show().)
From what I've noticed in Android you can double click on a button rapidly and have the onClick listener fire twice (or even more) regardless of the code in the listener (even if you disable the button immediately).
I reported a bug a while ago here: http://code.google.com/p/android/issues/detail?id=20073 but of course these things tend to go "unnoticed" by Google. Feel free to star it in hopes of getting Google's attention
I have a function that creates a socket connection and then waits for a response. During this time I do not want the user to be able to click any buttons, else they can crash the application.
as such at the start of the function I do the following:
public void Checkout()
{
AlertDialog.Builder builder2 = new AlertDialog.Builder(NuPos_testActivity.this);
builder2.setMessage("Processing");
AlertDialog alert2 = builder2.create();
alert2.show();
This greys out the screen and displays processing till the response comes back from the server. My problem is while this is the first thing at the top of the function it only runs after everything else. I don't understand why?
To be more clear about my problem: I run an alert box before code, but it only shows after the code has finished running. how do I fix this?
Showing an AlertDialog doesn't halt the code. It just prevents user interaction. If you want to delay further code execution until you are ready, look at something like ASyncTask which has an onPostExecute() method to notify you when the task is complete.
It sounds like your code sample above, and the code for your Socket, are running in the same Thread (which is the UIThread). If this is the case, Android will usually perform the 'processing' code first, and delay the painting until afterwards (as the painting has a lower priority).
You need to move the Socket code into a separate Thread, so that it can run independently from the UIThread, which should allow Android the time to display the AlertDialog earlier.
I'm really new to Java, especially working with GUI in Java.
I want to put a progress bar in my program, where it updates its value each time after certain amount of work has been done. Right now I have a button that executes a method when pressed, and I put setValue() function (with the value that I want) each time after certain work has been done in that method. However, when I press the button, the button seems to be stuck pressed while the method continues (the method takes a while to finish executing), and the progress bar doesn't get updated until all the other things has been done in the ButtonListener, so it goes directly to 100% after it's done).
What am I doing wrong?
Thanks in advance.
That is, most probably, because you are doing all work in main thread so it hangs your UI until all work is done. You should not do this. You should use separate EDT for such operations. What you should try is do your update progressBar job in separate EDT. Use SwingUtilities.invokeLater(Runnable r) for this.