java: how to delay code in GUI - java

I am making a programme in Java for a school project. It has the form of an interactive multiple-choice test.
I wanted it to perform it in a way that an action button creates an event in which (the order of the code is the same as listed):
1) Randomly chooses an Object that consist of several Strings from a prepared List and prints it on adequate text fields in GUI
2) Using a proper method there is a delay created that holds further code down below for 1 minute. In this time the user should be able to check proper Checkboxes so the GUI must stay active.
3)When this minute ends the checked places are read and further processed.
The thing is that I am unable to create step number 2) which is the delaying of the code below. I have tried function sleep() but when I do it with sleep() the whole GUI freezes and the user is unable to do anything on it. I have read that function swing timer would be appropriate but I dont know how to do it. I have seen examples but in them the timer along with functions that were executed after some time were written in the class ActionListener instead of the action button. I am using Netbeans 8.1
Sorry for my bad explanation of the problem, I am a total beginner in java programming and really count on your help :)
Cheers!

Your problem comes from how you structured your code. You wrote everything into a single method.
Split this up into two methods. One to set up the UI state (everything before "HERE I NEED TO DELAY..."). The second method takes everything below.
Then, at the end of the first method, create a non-repeating Timer for one Minute, add an ActionListener that just calls your second method. Then start the timer. When the timer has run its course, it will call your second method through the action listener.

Related

How to connect UI and functionality?

I am only a beginner in Java and until now I just put the functionality into the addActionListener() method of the buttons, it was enough for little games and stuff.
But now I am trying to make it seriously and I am wondering how to connect those 2.
As an example I am making a Fuchimi game, so I have my classes for the actual game and then a class that builds the frame with everything needed.
But my actual problem right now is, that after the frame is created, it doesn't do the following code since the code pauses at the window, like here:
FuchimiUI ui = new FuchimiUI();
//The following is not executed
Hand playerHand = null;
while (playerHand == null) {
playerHand = ui.getPlayerHand();
}
Hand enemyHand = generateHand();
ui.changeEnemyText("Enemy picked " + enemyHand.toString());
if (enemyHand.beats(playerHand)) {
ui.changeGenText("Computer wins!");
} else
ui.changeGenText("You win!");
The buttons I have just change the hand of the player.
So how can I do that properly, having the game code being compiled while the frame is already open?
I thought about threads, but I have too little knowledge about them, thus I don't know if that would be a good way.
Edit:
The ui.getPlayerHand() method returns the chosen hand(rock, paper or scissors) that the player has chosen through the buttons.
Of course I could have written the whole code in each of the button's addActionListener()methods, but I doubt that's the proper way of doing that.
So in general, all I wanted to do is let the player choose his hand and then let the game generate a random hand, then compare those two and change the text of one of the labels, depending on wether the player won or not.
The problem you are having results from the fact that your while loop is blocking the UI thread. You need to offload it to a different thread and then enqueue the UI updates back on the UI thread. The same situation is encountered here, please have a look.
There are several ways to fix this. One of them is the SwingWorker.
The steps are:
Override doInBackground for your while loop.
In it, call publish to store intermediate results (like the messages you want to display).
Override process to display the intermediate results in your UI.
The third page of above mentioned tutorial covers this.
As much as I agree with Domi's answer, that long-running code should go into a background thread, I strongly suspect that this is not what you need in this situation, that instead you should re-think the structure of your program. Likely what you need instead of that while loop is a modal dialog.
For more and better advice, consider telling us more details of the game logic and your program set up. For instance, tell us exactly what ui.getPlayerHand() does, as a start.
What you want to do is to change the structure of your program so that it is event-driven and state based where its behavior changes depending on its state. For instance if your program is in "choose hand" mode, then those buttons or other user interfaces are all that respond to the user.

Java add progressbar for current Thread

How can I add a progressbar that would show how much time will it take untill the current process in done?
I do know how to construct and use a progressbar, in simple ways, but I do not know how to bound them with a process.
For example when I click a button, I would like to open a jfilechooser, and this may take some time. I want the user to know that the app did not crash and to give an idea of how much time will it take until the jfilechooser appears.
Thanks in advance
The thing is, when dealing with classes you didn't write, it's not that easy to link the progress bar with the actual progress.
If you'd like to bind it with a progress of some task, here are the steps:
Assign a thread to the time-consuming task
Use a static field in the parent class as the progress you've accomplished in your task. (may be counter from 1 to 100)
Every specific period (1 sec) you check that static field and set the progress bar with it.
Inside your task, you divide your long process into solid steps (i.e. opening a file, processing, preparing extracted data ...etc).
After every solid step, update the static field in the parent class with the progress so far.
Make sure to regulate the process of writing and reading the static field using semaphores.

QT Jambi - QLCDNumber updated in real-time

In my university, we are working with interfaces, using QT Jambi (Java) with the Eclipse Integration.
I would like to improve my design of my Elevator interface.
The main problem is that I would like to update the QLCDNumber with the floor in real-time.
What I do to simulate the elevator working, is to do a Thread.sleep(1000) between 2 floors, so that way, my QLCDNumber will display "an animation" saying "1...2...3...4". The problem is that the QLCDNumber only displays 1 and 4, no animation.
So, for example (resumed), the code I made is this one:
private void simulate(int floor){
while(actualFloor < floor){
try{
Thread.sleep(1000);
}catch(InterruptedException e){};
actualFloor++;
ui.LCDfloor.display(actualFloor);
}
}
Why this code only shows the 1st floor and the last one?
Sorry if you didn't understand what I wanted, my English is improving every day :)
Thank you in advance.
*Please note that LCDFloor is the name of the QLCDNumber widget
It looks like you have two problems:
(I assume) You're calling Thread.sleep() on the GUI thread. In other words, when you call simulate, you're doing so on the same thread as the rest of the gui operations. This causes the entire gui to pause.
You've never given Qt the chance to actually update the UI. When you call ui.LCDfloor.display(actualFloor), the a paint event is queued so that the UI can be updated, but rather than giving the UI a chance to actually execute the paint event, you continue with your loop which prevents the UI from ever being updated until after your simulation is finished.
You have two basic fixes:
Don't sleep, it's poor design. Instead, use timer's and signals to simulate the changes.
Force events to be processed using processEvents.
Also keep in mind that you can't update a GUI element from a non gui thread. And as this is homework, I'll leave the rest to you :).

Threads and event handling in Java

I am a Java newbie and an Android newbie too. I am working on a game and trying to understand the exact nature of events in Java and Android. I have a few questions to help understand the correct way to do event handling in my app.
Its a network game and so I need to check if the user made a move or not to update the view. Also I need to prompt the user to make a move if he takes too long. For this I have two threads -
Timer thread expires every 10 seconds and calls updateview if needed or prompts user to make a move.
Event thread gets created when user clicks on the screen to make a move or clicks on menu etc.
Is this the correct approach? These two can be fired at any time.
Here are the issues I see with this -
What happens when one thread gets run when the other one is active.
Which thread has precedence if both are started at the same time.
Do events in the timer thread get queued up?
If so can I pick which one in the queue to use?
Can I cancel events in the queue? For e.g. if I have 2 updateview events lined up in the queue I only have to call it once.
Thanks for any inputs.
P
I would suggest reading up on Android AsyncTask.
Consider that you can implement a timer WiTHOUT using a thread. Use a single Handler switching on what and send a postMessageDelayed(what 0,milliseconds) to the handler say every one second. You could set a counter variable to zero and check the flag every one second in the what 0 handler, incrementing the counter by one. If the value is >= ten, post a message and reset the variable to zero. If the user selects an action, reset the instance variable to zero.
A time consuming action can be run in a separate thread that messages the handler, perhaps using what 1, on completion. Or you could run a time consuming action in a separate asyncTask.
JAL

Display objects in JFrame one at a time, or frame by frame

I've made a program in Java (eclipse) that displays squares and triangles on a grid using JFrame. The program determines where the objects go in a "for loop". I would like to have the objects appear one at a time (in a frame by frame type of approach). It seems like a "sleep loop" should be used to solve this problem. However I feel that a lack of understanding of java.awt*; is causing me problems. I adding the following to my "for loop"
try
{
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
}
catch(InterruptedException e)
{
e.printStackTrace();
}
The program waits, but draws the objects all at once after it is done sleeping. I have gone through my program and found that this "sleep" command is working to some extent (waiting before processing the next command) I put a println statement within said "for loop" to test it and the program waits one second before printing each println. But I don't know why JFrame draws everything only once at the end. Should I be using something like repaint() every time I want to display a new frame?
MY project structure is 3 classes. Main which simply calls DisplayFrame. DisplayFrame which sets up the Frame. And MyComponent which contains my "for loop" and the "sleep command".
Any help would be appreciated.
There is a tutorial here that uses a Timer to update an image at regular intervals. The example program is an applet, but the principle is the same.
sleep is probably a bad idea. Use a Timer instead:
http://download.oracle.com/javase/6/docs/api/javax/swing/Timer.html
From your description it is a little hard to guess what is going on, but I'm almost sure at least one of two bad things is happening:
you are sleeping in the EDT (Event Dispatch Thread) this locks the complete GUI and might be the reason for you not seeing any updates during sleep.
you are changing swing components from outside the EDT which is a sure way into concurrency hell.
Make sure you follow this approach:
Setup a Time to call you in the desired time intervall ( lets say every 0.1 seconds). In the method that is called manipulate you component/object to reflect the new state and call repaint.
let us know if it works. I'm not exactly sure about the repaint call ... might be wrong ..
Interestingly enough, the Applet Tutorial at the Oracle site has an example of an applet that performs an animation using SwingWorkers and Timers. Perhaps it can be useful to you.
Or you can take control of the rendering of the JFrame using concepts from the gaming world, as explained here

Categories

Resources