I want to add a timer that, on every tick of the timer (1second), causes the line to refresh. How do I use the timer in my code?
The following is my code:
LineRefresh.java:
package LineRefresh.xyz.com;
import java.util.Timer;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
public class LineRefresh extends Activity {
DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawView = new DrawView(this);
drawView.setBackgroundColor(Color.WHITE);
setContentView(drawView);
}
}
DrawView.java:
package LineRefresh.xyz.com;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLACK);
canvas.drawLine(50, 200, 270, 200, paint);
}
}
Here the sollution with Java's Timertask:
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
hereYourMethod();
}
}
};
timer.schedule(task, 1000,1000);// (the task, when to start, when to repeat)
Another way you can do this is the following:
Handler updateHandler;
#Override
public void onCreateBundle savedInstanceState) {
super.onCreate(savedInstanceState);
updateHandler = new Handler();
// Do this first after 1 second
updateHandler.postDelayed(RecurringTask, 1000);
}
Runnable RecurringTask = new Runnable() {
public void run() {
// Do whatever you want
// Call this method again every 30 seconds
updateHandler.postDelayed(this, 30000);
}
};
I had some trouble marshaling to the UI thread with the Timer/TimerTask solution, so here is another one that ended up working for me!
An alternative would be using a Handler.
mHandler = new Handler(new Handler.Callback()
{
#Override
public boolean handleMessage(Message msg)
{
if(msg.what == REFRESH)
{
// TODO Refresh Code
return true;
}
return false;
}
});
mHandler.sendEmptyMessageDelayed(REFRESH, mMilliSecondsToRefresh);
Then when you want it to stop (this should also go in onStop() so that it doesn't continue in the background when your app isnt active):
mHandler.removeMessages(REFRESH);
You can let the thread to sleep for 1 second:
Thread.sleep(1000); //1000 milliseconds = 1 second
If you're using Swing, best to use Swing timer: http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html
In your case, maybe you should use Timer: http://download.oracle.com/javase/6/docs/api/javax/swing/Timer.html
Related
I have a custom view and I overrided the ondraw. When I run my program the method invalidate updates the ondraw on my emulator but it doesn't work on real phone at all and the view is fixed on phone.
Anybody knows why?
here is my code:
package com.example.canvas;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.view.View;
public class Myview extends View{
String second="0";
int r=100;
public Myview(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
Paint paint=new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(12);
canvas.drawLine(getWidth()/2f, getHeight()/2f,getWidth()/2f+ ((r-18.0f)*(float)Math.cos(Math.toRadians((Float.valueOf(second)/60f*360f) -90.0f))) ,getHeight()/2f+((r-18.0f)*(float)Math.sin(Math.toRadians ((Float.valueOf(second)/60f*360f)-90.0f))), paint);
update();
super.onDraw(canvas);
}
private void update() {
Handler h=new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
Calendar c=Calendar.getInstance();
SimpleDateFormat ss=new SimpleDateFormat("ss");
second=ss.format(c.getTime());
invalidate();
}
}, 1000);
}
}
Bingo!when I set timezone for calendar object to my country,invalidate worked and ondraw was updated on emulator and real phone.
My goal here is to have some animation on a node (such as a fade transition) that serves as a temporary notice that something is happening. I want the animation completely gone, like it never happened when that something has ended.
The code snipped below is an example of the problem I'm having. In the current state, when the button is hit to stop the process the button just stays at it's current opacity. If the commented line is uncommented, the button no longer stays at it's current opacity but updates to look correct. My problem then is that when the button is hit again, the CSS opacity for the default stylesheet (Modena.css for JavaFX 8) is no longer taking effect.
Is there something I'm doing wrong, or is there a better way altogether?
package gui.control.custom;
import javafx.animation.Animation;
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Test extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Stage stage = new Stage();
HBox box = new HBox();
streamButton = new Button("Start");
streamButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if (started) {
stopProcess();
} else {
startProcess();
}
}
});
box.getChildren().add(streamButton);
stage.setScene(new Scene(box));
stage.show();
}
FadeTransition ft;
Button streamButton;
boolean started = false;
private void startProcess() {
streamButton.setDisable(true);
new Thread() {
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
}
Platform.runLater(() -> {
started = true;
streamButton.setText("Stop");
streamButton.setDisable(false);
startButtonAnim();
});
}
}.start();
}
private void stopProcess() {
streamButton.setText("Start");
stopButtonAnim();
started = false;
}
private void startButtonAnim() {
ft = new FadeTransition(Duration.millis(500), streamButton);
ft.setFromValue(1.0);
ft.setToValue(0.3);
ft.setCycleCount(Animation.INDEFINITE);
ft.setAutoReverse(true);
ft.play();
}
private void stopButtonAnim() {
ft.stop();
//streamButton.setOpacity(1);
}
public static void main(String[] args) {
launch();
}
}
I think the best solution is to use jumpTo(Duration duration) right before you stop the Animation. Setting the duration to Duration.ZERO.
Circle circle2 = new Circle(250, 120, 80);
circle2.setFill(Color.RED);
circle2.setStroke(Color.BLACK);
FadeTransition fade = new FadeTransition();
fade.setDuration(Duration.millis(5000));
fade.setFromValue(10);
fade.setToValue(0.1);
fade.setCycleCount(1000);
fade.setAutoReverse(true);
fade.setNode(circle2);
fade.play();
Button btnStop = new Button("Stop");
btnStop.setOnAction((event) -> {
fade.jumpTo(Duration.ZERO);
fade.stop();
});
Another idea:
I have found this method in javadoc: getCurrentRate(),
which should give you negative result on reversing, so the code would look like this:
private void stopButtonAnim() {
while(ft.getCurrentRate>=0); //waiting till animation goes (skips if already reversing)
while(ft.getCurrentRate<=0); //and till reverse
ft.stop(); //then stop
streamButton.setOpacity(1); //make it 100% ;)
}
Maybe you have to add Thread.sleep(int) to while cycle
I would try this insetad of simply stop(); this line
setOnFinished(e->tryToStop());
And create this method as:
public void tryToStop(){
if(!started)
fm.stop();
}
stopProcess() method changes the started variable, so it will stop in this two cases:
if it is finished
AND
if it is reqested to stop
Not tested, just an idea
I'm currently trying my hand at LibGDX to create a simple game. Currently I have finished working on the main menu and have tried to program the Level Selection menu. I have the following code in my LevelSelection class but my application crashes when I try to click on the "start" button in my main menu to bring up the Level Selection menu:
import java.util.ArrayList;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
public class LevelSelect implements Screen {
private Stage stage;
private TextureAtlas atlas;
private Table table;
private ArrayList<TextButton> buttons;
private Skin skin;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
}
public void initButtons(){
buttons = new ArrayList<TextButton>();
for(int i=1;i<=5;i++){
TextButton b = new TextButton(("" + i),skin);
buttons.add(b);
}
}
#Override
public void resize(int width, int height) {
/*stage.getViewport().update(width, height, false);
table.invalidateHierarchy();*/
}
#Override
public void show() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
atlas = new TextureAtlas(Gdx.files.internal("ui/button.pack"));
skin = new Skin(Gdx.files.internal("ui/menuSkin.json"),atlas);
table = new Table(skin);
this.initButtons();
}
#Override
public void hide() {
dispose();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
stage.dispose();
skin.dispose();
}
}
It seems that the initButtons method isn't the issue either as even without that the application crashes. The application reports no errors, rather I get a Java Platform SE binary has stopped working issue when I click the 'start' button that loads this new screen class.
Thank you for your help!
package com.bzgames.minecraftbz;
import android.content.Context;
import android.util.Log;
import android.view.View;
public class GameView extends View implements Runnable {
private static final long INTERVAL = 10;
private boolean running;
public GameView(Context context) {
super(context);
Thread minhaThread = new Thread(this);
minhaThread.setPriority(Thread.MIN_PRIORITY);
minhaThread.start();
}
#Override
public void run() {
while (running){
try {
Thread.sleep(INTERVAL);
} catch (Exception e) {
Log.e("Erro", e.getMessage());
}
}
}
public void release(){
running = false;
}
}
How do I change the background layout with Java? I tried using the bitmap but I am unable to change the background of the layout the same way.
You can do this 3 ways, as far as I know, programatically:
1- With canvas and a repaint method.
2- With big bitmaps:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
3- Using methods like "setImageResource(...)"
android imageview.setBackgroundResource() doesnt work
But as you're dealing with games, I suggest you use Canvas or some other framework that will give you more support to manipulate graphic elements.
Boa sorte!
i am making an app to make the hands of a clock.That is, i draw a simple line on the screen and want it rotate like the hands of a clock.how do i do this using a timer?(so that the position of the line refreshes).Only one end point of the line should rotate,while the other remains staionary.In the folllowing code,i only draw a line on the screen:
DrawView.java:
package LineRefresh.xyz.com;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(final Canvas canvas) {
paint.setColor(Color.BLACK);
canvas.drawLine(50, 200, 270, 200, paint);
}
}
LineRefresh.java:
package LineRefresh.xyz.com;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
public class LineRefresh extends Activity {
DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawView = new DrawView(this);
drawView.setBackgroundColor(Color.WHITE);
setContentView(drawView);
}
}
Try something like this:
private Handler mHandler = new Handler();
private Runnable MethodToDrawClockLine = new Runnable()
{
public void run()
{
//execute here your drawing routine.
// after drawing set the timer for another x period of time
mHandler.postDelayed(MethodToDrawClockLine, 1000); //it'll re-execute it after 1sec.
}
}
in you OnCreate or any method where you want to Start the Timer you can use:
mHandler.removeCallbacks(mUpdateTimeTask); //be sure to remove any handler before add a new one
mHandler.postDelayed(MethodToDrawClockLine, 1000); //it'll execute it after 1sec.
when you're done, remember to remove the handler.
mHandler.removeCallbacks(mUpdateTimeTask);
That shold be it.