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.
Related
Okay, so this problem has been plaguing me for the past few days. And before anyone comments about it, yes I have made the jframe visible and I have added all the components that I need to it. Also, all components are added well before the GUI is set to visible and activate() is called.
So I am trying to run a couple simeple lines of code.:
g.setVisible(true);
g.activate();
Simple enough. g is an object made from a class I made GUI which extends JFrame. and activate() is a method that runs an infinite loop that just does a bunch of things until the user tells it to exit. However, when the program gets to the g.setVisible() line it opens a JFrame that is the size I specified however is completely devoid of anything. Then it moves onto the g.activate(); which at the moment runs for a specific amount of iterations and stops. At which point it finally decides that it can go back and display my GUI. The issue with that is that the GUI is meant to be updated by the loop from active() and keep the user in the know of what is going on.
Any help is appreciated let me know if you need more detials and thank you in advance.
In many different UI frameworks, it's common for the methods you call to queue some work rather than perform it immediately. From your description, it seems like setVisible() may be creating a native window but then queuing the rendering of the components. Since this code is (presumably) running in the UI thread, it won't perform the work it queued until after running activate().
Long-running tasks should never be run on the UI thread. In Swing, you can use SwingWorker or explicitly create a background thread.
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
How do I make it so that the program doesn't keep reading in code until the button is clicked?
Why?: I have a 10x10 grid with buttons in each part and then code running depending on what is clicked. However, my program keeps reading in code so there is never a choice being made and it gives me error. I tried giving it a infinite loop until a button is pressed, but that doesn't work out so well
-edit
I'm a complete beginner with Java.
This is a picture of the GUI
http://imageshack.us/content_round.php?page=done&l=img843/5351/sascp.png
What I want is for the code to not keep running step by step until I click a button.
E.G.:
create gameGUI
wait until and check which button is pressed
if(buttonClicked[i][k] == something){
System.out.println("lool");
}
But what's happening in my code is that it creates the gameGUI and then because the user isn't fast enough to click it just skips over the if statement or gets a run-time error because nothing was pressed.
In both Android & Swing (& I'd expect J2ME), buttons fire events when told to do so (by activating them). You would generally just wait for that to happen before doing anything, and not bother with what the rest of the GUI is doing (or not doing) at the time.
Or in other words:
Add an ActionListener to the buttons.
In the actionPerformed() method, insert the code that you have above.
Also
The code snippet provides almost no useful information. For better help sooner, post an SSCCE.
That GUI looks like Swing to me. If it is not, then what is it?
Please always copy/paste run-time errors.
This is for the swing experts out there. I have spent considerable time on this problem, so it is going to take me a few lines to explain the problem.
I have a standalone java swing application (java 6). In my application, I have a frame with a radio button group. I have a single action linked to all the buttons in the group. The action checks to see which radio button is selected and performs some work. The "work" involves some background computation as well as some painting in two other frames in my application. The background computation is multi-threaded.
I would like to display a progress bar when the user selects one of the radio buttons.
However, when a radio button is selected, while the action to the radio button is happening, the progress bar never appears. I have tried jdialog type progress bars, glass panes, etc. None of them appear until the "work" is all completed. This seems to be because Swing does not finish painting the radio button until the "work" in the corresponding action is completed. And since the EDT only does one thing at a time, the progress bar dialog (or glass pane) is never displayed.
I then tried to use a SwingWorker to do all this "work". Start the progress bar (or activate a glass pane), start the SwingWorker and close the progress bar (or deactivate the glass pane) in the done() method for the SwingWorker. This seems to bring up the progress bar fine, but the painting which is part of the "work" is sometimes not completed, leaving me with some painting artifacts (the paintComponent method is pretty complicated, so do not want to reproduce here). The artifacts disappear if I resize the window. In fact, this happens if I use a class which extends Thread instead of SwingWorker too. This is all because Swing is not threadsafe and I am trying to do GUI work from a thread other than the EDT. I understand that part.
What do I do? "work" takes about 30 seconds and that seems too long to go without showing the user some kind of indication that the program is working. I have also tried changing the cursor to a wait cursor and have run into the same problems as above. The only thing that I can do is disable the frame and set the title of the frame to some text like "working..."
Anybody seen this problem before?
I think you are right to do the work in the SwingWorker thread, but you shouldn't be trying to do your painting there.
I'd be inclined to:
Have the ActionListener show() the progress bar, set off the swingworker then exit
Have the worker thread do the work, and periodically call repaint() on the progress bar component (this is guaranteed to be thread safe)
Progress bar has it's own paintComponent (which will be automatically called on the EDT). If necessary, this can read some variable that is updated by the worker thread to measure progress
When the worker thread finishes, have it call invokeLater() to run a final close down function on the EDT, which will hide the progress bar and do any other GUI-related cleanup / show a completion message to the user etc.
When you moved the work from the EDT to the swing worker (which was the right thing to do), it sounds like both the work and the painting moved to the swing worker. The painting should still happen on the EDT. You can achieve this by using SwingUtilities.invokeLater to invoke a repaint from the background thread, or by using the SwingWorker.publish(V...), which will take notifications from your worker thread and make them available on the EDT via the SwingWorker.process(V...) template method (which you override). Your process override can handle the intermediate notifications by repainting a portion of the screen, updating progress, or taking some other appropriate action as desired. Any UI changes done here will be visible without waiting for the rest of the work to complete.
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.