I'm trying to build a count-down timer function in my app, however, it doesn't run as expected.
timer = new CountDownTimer(100, 10) {
#Override
public void onTick(long l) {
Log.d(TAG, "onTick: " + l);
}
#Override
public void onFinish() {
}
}.start();
My expectations are that it would count down gradually from 100,90,80...till 0
Although the output timer is showing quite random times (34 then 18 then 8..etc).
How can I achieve what I want?
It's difficult to explain the exact idea I'm trying to achieve but basically, I'm using touch listeners to hover over an item which in turn loads a few other items in the view. For some reason, there should be an intentional delay of around 100ms before these items could be displayed. I'm trying to build a progress bar that tells the user that something is loading rather than giving the impression that the screen is just stuck. I hope that helps to give a better idea of what I'm trying to achieve
Related
I am a new user and have a question
how to auto roll activity with random countdown time ?
example : ActivityScreen1 display time in 50s-60s -> ActivityScreen2 display time in 30s-40s -> ActivityScreen2 display time in 50s-60s.
Still I want you to learn Android first from some good tutorials. But I can guide you how you can achieve this.
You will make a Service. Which will run in background.
You will make a Handler in your service. That will call postDelayed() method.
Like this
final Runnable r = new Runnable() {
public void run() {
changeActivity(); // make this method & add your logic of checking current activity & setting new
}
};
handler.postDelayed(r, 1000); // 1000 is millisecond, you will set time here.
I'm having a problem I'm making a pool game and I need the ballos to react when I simulate a hit, the program works like this, you click the direction and power to hit the ball and the click go, the go button is in the GUI class where my labels are created, the button calls a method from my main class that recieves the parameter and then with a while in it, changes the X and Y of the ball till the power is reduced to 0 and then stops, the code is working, but the ball moves until the while stops. So the while works and when the power int is 0 the while goes out and then the new X,Y are painted.
This is the funcion that the button calls, the button sends all the parameters
public void golpe(int pbola, int pvelocidad, String pdireccion, JLabel[] listalabels) throws InterruptedException{
listabolas[pbola].setVelocidad(pvelocidad);
listabolas[pbola].setDireccion(pdireccion);
while (listabolas[pbola].getVelocidad() > 0) {
moverBola(pbola, listalabels);
//System.out.println(listabolas[pbola].getPosX());
//System.out.println(listabolas[pbola].getPosY());
Thread.sleep(500);
//This line is supposed to change the X and Y of the object over and over
//but only does it till the end
listalabels[pbola].setLocation(listabolas[pbola].getPosX(), listabolas[pbola].getPosY());
}
}
Here is the function moverbola(), only copied one "if" so that the code doesn't look to big
private void moverBola(int pbola, JLabel[] listalabels) {
if (listabolas[pbola].getDireccion().equals("SE")) {
int pposX = listabolas[pbola].getPosX();
listabolas[pbola].setPosX(pposX + 1);
int pposY = listabolas[pbola].getPosY();
listabolas[pbola].setPosY(pposY + 1);
}
Swing is a single threaded framework. That is, all interactions with UI are expected to occur from within a single thread, known as the Event Dispatching Thread.
Any action that blocks this thread, will prevent the EDT from updating the screen or processing any new events.
Your while-loop is blocking the EDT, preventing it from painting any updates until after the while-loop is completed.
Take a look at Concurrency in Swing for more details.
There are a number of approaches you could take...
You could use a Thread, but this causes problems as you need to ensure that any changes you make to the UI are re-synced back to the EDT and this can become messy...
For example
You could use a javax.swing.Timer that ticks at a regular interval and you would update any internal parameters from within it's assigned ActionListener. Because the tick events occur within the EDT, it is save to update the screen from within it.
For example
You could use a SwingWorker to run the task in the background. It has methods for re-syncing updates back to the EDT, but might be a little over kill for your purposes...
Updated with a possible Timer example
Caveat- It is very hard to produce a reasonable example with only a code snippet, but, something like this might work
public void golpe(final int pbola, int pvelocidad, String pdireccion, final JLabel[] listalabels) throws InterruptedException{
listabolas[pbola].setVelocidad(pvelocidad);
listabolas[pbola].setDireccion(pdireccion);
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (listabolas[pbola].getVelocidad() == 0) {
((Timer)evt.getSource()).stop();
} else {
moverBola(pbola, listalabels);
}
}
});
timer.setRepeats(true);
timer.start();
}
This question refers to andengine GL-ES1.
I am having trouble making a wallpaper activity that refreshes when your return to it, or when the user performs actions in the game.
My game has two activities. In one, you can edit and arrange the background elements in a room. In the other you play the game, and it uses the same background with the elements you arranged in the first activity.
There is also a live wallpaper in which your room is the background and characters move around in front of it.
I am making updtaes in onResume() in the wallpaper.
first I detach all the backgroudn sprites i used before.
Then I attach new sprites in the updated positions.
What happens is: some of the sprites don't show up.
Here is the method: Can you see anything I'm doing wrong?
private void loadBackgroundDecorations() {
//Add new decorations
Log.d(TAG, "loadBackgoundDecorations");
mEngine.runOnUpdateThread(new Runnable() {
#Override
public void run() {
// Remove Old Decorations
Log.d(TAG, "loadBackgoundDecorations: decorationList.size() =" + decorationList.size());
while(decorationList.size() > 0){
Sprite d = decorationList.remove(0);
scene.detachChild(d);
Log.d(TAG, "loadBackgoundDecorations: detachChild");
}
decorationList.clear();
//Add new decorations
ArrayList<Integer> decorations = app.getBackgroundManager().getDecorations();
Log.d(TAG, "loadBackgoundDecorations: decorations.size()" +decorations.size());
for (int i = 0; i < decorations.size(); i+=3) {
Log.d(TAG, "Decoration Values: texture-"+decorations.get(i)+", x-"+decorations.get(1+i)+", y-"+decorations.get(2+i));
Sprite draggable = new Sprite(decorations.get(1+i),decorations.get(2+i),mGameTextureRegionLibrary.get(decorations.get(i)));
draggable.setIgnoreUpdate(true);
scene.attachChild(draggable,0);
decorationList.add(draggable);
Log.d(TAG, "loadBackgoundDecorations: attachChild"+ i);
}
}
});
}
#Override protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
BitmapTextureAtlasTextureRegionFactory.createFromAsset(mTexture, this, app.getAquariumBackground(), 0, 0);
addBubbles();
loadBackgroundDecorations();
addCharacters()
}
============ UPDATE =================
As some people have suggested below, I tried adding all the scene setup functions into the runnable. This has no effect. What has worked for me is to set the "wrong" decorations visible property to "false". But I am worried that this will eventually cause a memory leak as more and more duplicates of the sprites are hidden on the wallpaper.
The problem only exists when I call "detachChild". For some reason that seems to prevent "attachChild" from firing correcly. Anybody have ideas for what could be causing this?
Can anyone else create an activity that adds and removes sprites in the onResume function?
I am fairly certain that the error has to do with your onResume method. The order you have your methods in is
addBubbles();
loadBackgroundDecorations();
addCharacters()
but your loadBackgroundDecorations uses a runnable so there is no guarantee that the method will run in between.
My Explanation:
From what I understand both addCharacter and addBubbles will be running on the UIthread whereas the loadBackgroundDecorations method will run on the update thread. The two threads will go through the methods at different times and that is where you are seeing some inconsistencies.
To Fix:
Put addBubbles and addCharacters in the same runnable in the order that you want and it should work as expected.
I am having an issue with SWING GUI or at least I think it is the swing gui.
Here is my main code file:
/**
*
*/
package com.tda.t2.ctas.slasher;
import javax.swing.SwingUtilities;
import com.tda.t2.ctas.slasher.gui.mainFrame;
import com.tda.t2.ctas.slasher.utils.MyCloseListener;
public class SLASHer {
public SLASHer () {
}
/**
* #param args
*/
public static void main(String[] args) {
//EventQueue.invokeLater(new Runnable() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ConfigData myconfig = new ConfigData();
try {
//TdaUrlHelper window = new TdaUrlHelper();
//window.tdaFrame.setVisible(true);
mainFrame tdaFrame = new mainFrame();
tdaFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
Simple call to create the frame and open it. There are other files that I did not put here for space. But the problem that I have (and I have tried on several machines and operation systems) is that the buttons on the window seem to hang. I can select the window and click on the buttons and they highlight like they were hit but nothing happens. I have a tabbed plane and clicking on the other tabs also does nothing. Some times this last for about 15 seconds and other times it lasts several minutes. But it always eventually comes back and will respond to new input (ie it does not remember all the click around I did before it came back). The application overall is simple in that it sits waiting until a user does something before it does something so I am confused on why it seems to hang.
Any help would be appreciated.
Thanks
What is the offending code attach to the button that hangs? Check your console for exceptions, and put some System.out.println() statements at the top and bottom of that code. See if you see those print statements print out. Watch how long it takes for the one at the top to print and bottom one to print. If you see both statements then you know that whole block is executing, but if it takes a while to show the last statement you know you are hanging up the Swing thread (also known as EDT - event dispatch thread). Rule number one in Swing the UI can't repaint while it's executing your ActionListener.
In order to make a responsive UI you have to see the first and last statement appear on the console in under 10-100ms (visually almost instantaneous). If you really want to get fancy you can use System.currentTimeMillis() at the stop and bottom. Subtract the two values and println() it. That'll tell you exactly how long that listener ran for. If it's greater than 100ms you need to restructure your code by either improving your algorithm or off loading the long calculation on a thread (see this SwingWorker tutorial).
public void actionPerformed(ActionEvent event) {
System.out.println("Starting SomeProcess");
long start = System.currentTimeMillis();
// all your code belongs here
long duration = System.currentTimeMillis() - start;
System.out.printf("SomeProcess took %,d ms%n", duration );
}
I want to create a simple clock using Java. The code is so simple that I will give an example:
for(int i=0;i<=60;i++)
jLabel11.setText( Integer.toString(i) );
The problem is while I'm running my program the result didn't show each update in sequence.
It show only the 60 digit immediately, without showing the change from 1 to 2 to 3 ...
How can i fix this problem?
The problem is that changes to the UI should run on the event dispatch thread, but blocking this loop (and blocking the UI) will stop the screen from repainting. Instead, use a timer to perform regular updates, e.g.
Timer timer = new Timer();
ActionListener updater = new ActionListener()
{
int count;
public void actionPerformed(ActionEvent event) {
jLabel11.setText( Integer.toString(count++) );
if (count==60)
timer.stop();
}
}
timer.setDelay(100);
timer.addActionListener(updater);
timer.start();
See the Sun Tutorial - How to use Swing Timers.