I have got my custom widget that changes background when hover. It is working nice but I would like to have smooth transition between no background and hover background. It will work with GC.setAlpha(), but:
Display.getDefault().asyncExec(new Runnable() {
public void run() {
for (int i=0;i<255;i++) {
setBG(BGHelper(imgHover,i)); //i - alpha
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
This code wait until i == 255, but it doesn't display a smooth transition. Why?
This can not work, because as long as you are in your Code SWT will not repaint or change the component.
You should do the work in a separate Thread and call Display.asyncExec for every change.
for (int i = 0; i < 255; i++) {
final int x = i;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
setBG(BGHelper(imgHover,x)); //x - alpha
}
});
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Related
I'm new in Java (still learning) all the other works have gone well but only this animation gives my headache and the coffee won't even help=(!
I should make an animation of Javaman (10 gif pictures named as T1, T2,...T10) I should use Thread, MediaTracker-class and addImage-method. Then I should specify the speed of the animation by using sleep-method (I used join-method if that's right??).
(MY JAVA CODE GOES LIKE THIS)
import java.applet.Applet;
import java.awt.*;
public class Animaatio extends Applet implements Runnable {
Image[] images = null;
MediaTracker tracker = null;
int current = 0;
Thread animThread;
#Override
public void init() {
// Creating a new media tracker, to track loading images
tracker = new MediaTracker(this);
// Creating an array of ten images
images = new Image[10];
// Downloading the images
for (int i = 0; i < 10; i++) {
// Loading the images
images[i] = getImage(getCodeBase(), (i + 1) + "T.gif");
tracker.addImage(images[i], 0);
}
try {
tracker.waitForAll();
} catch (InterruptedException e) {
}
}
#Override
public void start() {
if (animThread == null) {
animThread = new Thread(this);
animThread.start();
}
try {
animThread.join();
} catch (InterruptedException e) {
}
}
#Override
public void paint(Graphics g) {
g.drawImage(images[current++], 0, 0, this);
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
}
}
The problem is that I don't see any animation just an empty applet viewer which just keeps running. Problem might be caused if the images are storaged in the wrong place? If someone could wreally help me, I would be really thankful for my knight=).
#Override
public void run() {
act.runOnUiThread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < randomNumber.size(); i++) {
Log.d("N",randomNumber.get(i).toString());
if (randomNumber.get(i).intValue() == 1) imgColor.setBackgroundColor(Color.RED);
if (randomNumber.get(i).intValue() == 2) imgColor.setBackgroundColor(Color.GREEN);
if (randomNumber.get(i).intValue() == 3) imgColor.setBackgroundColor(Color.BLUE);
if (randomNumber.get(i).intValue() == 4) imgColor.setBackgroundColor(Color.YELLOW);
try {
Thread.sleep(1750);
} catch (Exception e) {
Thread.currentThread().interrupt();
}
imgColor.setBackgroundColor(Color.BLACK);
try {
Thread.sleep(400);
} catch (Exception e) {
Thread.currentThread().interrupt();
}
}
Toast.makeText(act, "Ripeti la sequenza", Toast.LENGTH_SHORT).show();
}
});
}
I have a number list, with numbers from 1 to 4. I want to picture the ImageView according to the numbers in the list, but I need a sequence of colors, so I need (for example) show the RED color, after wait 1,75 seconds, and after the GREEN and so on, but it doesn't work ! What should I do ?
For such tasks Thread isn't the best choice. I recommend you to use View.postDelayed method. So you should get something like that.
void setRandomColor(){
if(!hasRandomColor())
return;
imgColor.setBackgroundColor(getRandomColor());
imgColor.postDelayed(new Runnable(){
void run(){
setRandomColor();
}
}, 1750); // update color again after 1.75 sec
}
...
setRandomColor();
I'm using a Thread to scroll text in my application :
public void run() {
super.run();
while (!isInterrupted()) {
if (X >= -getPreferredSize().getWidth()) {
X -= 2;
} else {
decrementMessagesInList(getMessages());
addMessage(getMessages());
prepare();
X = getParentWidth();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
repaint();
}
}
However, see that with sleep my CPU usage is very high, I need to reduce that. Can anyone suggest how to do it ?
If I can make the assumption that your code only needs to scroll the text in response to some event (say a click or drag or something) then you should make your thread go into a wait state then have the code that triggers the update post a notification over to the thread which will then wake up and do the update. Something like this:
Object syncObj = new Object();
public void run() {
while (true) {
try {
syncObj.wait();
if (X >= -getPreferredSize().getWidth()) {
X -= 2;
} else {
decrementMessagesInList(getMessages());
addMessage(getMessages());
prepare();
X = getParentWidth();
}
repaint();
} catch (InterruptedException ie) {
// handle the exception
}
}
}
Then in the code which handles/generates the event that causes a need to scroll
public void onClick(..) {
syncObj.notifyAll();
}
You also need to guard against spurious wake ups of your thread to make sure the event you were waiting for actually happened. See Do spurious wakeups actually happen?.
I have a android that draws a mandelbrot image.
I have 16 threads that each draw 1/16 part of the image, they have their own bitmap.
for(int x=0;x<xw;x++) {
for(int y=0;y<yh;y++) {
c_real=realMin+((double)(x+x1)*scaleReal);
c_imag=imagMin+((double)(y+y1)*scaleImag);
tmp=cal_pixel(c_real, c_imag, mag);
while(pause[thread]) {
try{
Thread.sleep(5);
}catch(InterruptedException ie){
}
}
plot(x,y,c[tmp], thread);
active[thread]=true;
}
dirty=true;
}
public void plot(int x, int y, int c, int myId) {
bitmap[myId].setPixel(x, y, c);
}
The run method for each piece
public void run() {
int myId=id++;
Log.i("run","Starting thread "+myId);
while(true) {
if (redraw[myId]) {
Log.i("run","redraw");
calc(myId);
redraw[myId]=false;
}
try{
Thread.sleep(100);
}catch(InterruptedException ie) {
}
}
}
I have a separate thread that 10 times a second takes the bitmaps and draws them on the canvas.
image.pause(true);
for(int i=0;i<16;i++) {
c.drawBitmap(image.getBitmap(i), (i%4)*w/4, (i/4)*h/4, null);
}
image.pause(false);
This is the thread that draws them
public void run() {
Canvas c;
while (true) {
if (run) {
if (view.dirty()) {
c = null;
try {
c = holder.lockCanvas(null);
synchronized (holder) {
view.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
holder.unlockCanvasAndPost(c);
}
}
}
try{
Thread.sleep(100);
}catch(InterruptedException ie){
}
}else{
//Log.i("Waiting the night away","Waiting the night away");
try{
Thread.sleep(1000);
}catch(InterruptedException ie){
}
}
}
}
Sometimes one or several of these pieces gest screwed up and are not drawn to the canvas, any idea why that happense.
It worked better in android 2.3.x it almost never happened, but noww in android 4.x it happens qquite often, if you want to check the program out and experience the bug here is the link https://play.google.com/store/apps/details?id=se.klockar.mandelbrotmobile
In my android application I want an automatically refresh every 60 seconds. So I tried it like this:
public void refresh_check() {
Thread myThread = new Thread()
{
int counter = 0;
#Override
public void run() {
MyActivity.this.runOnUiThread(new Runnable(){
#Override
public void run() {
while (counter < 60) {
try {
Thread.sleep(1000);
counter += 1;
System.out.println("Counter: " + counter);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
refresh();
}});
super.run();
}
};
myThread.start();
}
This works in the way that it prints the counter into logcat but in my Application I get a black view. refresh() is just a function with a http request, and this works alone, so the mistake has to be in the thread at any place :/ Can someone help?
You are not utilizing the Thread correctly. Running long tasks on the UI thread is just like not using a Thread at all. To accomplish what you need you should do it like this:
public void refresh_check() {
Thread myThread = new Thread()
{
int counter = 0;
#Override
public void run() {
while (counter < 60) {
try {
Thread.sleep(1000);
counter += 1;
System.out.println("Counter: " + counter); //I think this may cause exception, if it does try removing it
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
refresh(); // In refresh(), use TextView.post(runnable) to post update the TextView from outside the UI thread or use handlers
}});
super.run();
};
myThread.start();
}
Also, take a look at AsyncTask class, it enables you to run long tasks outside UI thread (doInBackground()) as well as update UI with the result from (onPostExecute())