Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
walkline
Posts: 82
Registered: ‎01-10-2013
My Device: Bold 9900
Accepted Solution

Thread not invoked in a Customized Field?

This is a block field of game 2048, I want to made an animation effect to show a new block to its manager, but it's not worked.

 

package com.walkline.util.ui;

import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.FontFamily;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiApplication;

import com.walkline.util.Function;

public class BlockField extends Field
{
	private static Font _font;
	private static final int CORNER_RADIUS = 12;

	private Object LOCK = new Object();
	private int _value = 0;
	private int _fore_color = 0;
	private int _background_color = 0;
	private String _text = "";
	private int _animation_size = 0;

	public BlockField()
	{
		super(NON_FOCUSABLE);

		try {
			int fontSize = 7;
			FontFamily family = FontFamily.forName("Tahoma");

			if (Display.getWidth() > Display.getHeight())
			{
				if (Display.getWidth() > 480) {fontSize = 9;}	
			} else {
				if (Display.getHeight() >= 480) {fontSize = 9;}
			}

			_font = family.getFont(Font.EXTRA_BOLD, fontSize, Ui.UNITS_pt);
		} catch (ClassNotFoundException e) {}
	}

	public void clear() {setValue(0);}

	public int getValue() {return _value;}

	public void setValue(int value)
	{
		_value = value;
		_text = ((value != 0) ? String.valueOf(value) : ""); 

		_fore_color = ((_value > 4) ? 0xf9f6f2 : 0x776e65);
		setBackgroundColor();
	}

	public void setBackgroundColor()
	{
		switch (_value)
		{
			case 0:
				_background_color = 0xccc0b3;
				break;
			case 2:
				_background_color = 0xeee4da;
				break;
			case 4:
				_background_color = 0xeee0c8;
				break;
			case 8:
				_background_color = 0xf2b179;
				break;
			case 16:
				_background_color = 0xf59563;
				break;
			case 32:
				_background_color = 0xf67c5f;
				break;
			case 64:
				_background_color = 0xf65e3b;
				break;
			case 128:
				_background_color = 0xffedcf72;
				break;
			case 256: 
				_background_color = 0xffedcc61;
				break;
			case 512:
				_background_color = 0xffedc850;
				break;
			case 1024:
				_background_color = 0xffedc53f;
				break;
			case 2048:
				_background_color = 0xffedc22e;
				break;
			case 4096:
				_background_color = 0xff3c39;
				break;
		}
	}

	public void startRun()
	{
		Thread thread = new Thread(new Runnable()
		{
			public void run()
			{
				while (_animation_size < getWidth());
				{
					Function.errorDialog("size: " + _animation_size + ", width: " + getWidth());	

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {new Exception("thread exception: " + e.toString());}

					_animation_size += 10;
					if (_animation_size > getWidth()) {_animation_size = getWidth();}

					invalidate();
				}
			}
		});
		thread.start();
	}

	protected void layout(int width, int height)
	{
		_animation_size = width / 2;
		setExtent(width, height);
	}

	protected void paint(Graphics g)
	{
		g.setColor(_fore_color);
		g.setFont(_font);
		g.drawText(_text, (getWidth() - _font.getAdvance(_text)) / 2, (getHeight() - _font.getHeight()) / 2);
	}

	protected void paintBackground(Graphics g)
	{
		g.setColor(_background_color);
		g.fillRoundRect((getWidth() - _animation_size) / 2, (getHeight() - _animation_size) / 2, _animation_size, _animation_size, CORNER_RADIUS, CORNER_RADIUS);
	}
}

 

In the startRun() method, I change the paint size and call invalidate(), but it's looks like the code not worked in the run() block, anyone knows how to make it effective?

Please use plain text.
Developer
peter_strange
Posts: 19,604
Registered: ‎07-14-2008
My Device: Not Specified

Re: Thread not invoked in a Customized Field?

[ Edited ]

When debugging, which of your lines are actually executed?

 

I am surprised this actually compiled since I don't know what Object your invalidate() is actually targetting.  You need to invalidate the Field that is displaying your animation. 

 

Edit:  On reflection the paragraph above makes no sense, please ignore it.

Please use plain text.
Developer
walkline
Posts: 82
Registered: ‎01-10-2013
My Device: Bold 9900

Re: Thread not invoked in a Customized Field?

 

public void startRun()
	{
		Thread thread = new Thread(new Runnable()
		{
			//code can be executed in this line
			public void run()
			{
				while (_animation_size < getWidth());
				{
					//once into while() block, nothing will be executed
					Function.errorDialog("size: " + _animation_size + ", width: " + getWidth());	

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {new Exception("thread exception: " + e.toString());}

					_animation_size += 10;
					if (_animation_size > getWidth()) {_animation_size = getWidth();}

					invalidate();
				}
			}
		});
		thread.start();
	}

hi, peter, in actually, there's no line be executed in above code block........

 

After debugger, I found that once the code executing into run() block, but not into while() block, lines can be executed, however, lines in while() block will never be executed.

 

About the invalidate() section, I have been append below codes inside Field Class used to instead of invalidate() in startRun() block.

public void refresh() {this.invalidate();}

 It's still useless, since the codes inside whie() block will never executed........

Please use plain text.
Developer
simon_hain
Posts: 16,137
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport

Re: Thread not invoked in a Customized Field?

add some debugging code to find out why. set a variable to getWidth and use a sysout to print both width and _animation_size.
is startRun called from outside?
----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Please use plain text.
Developer
walkline
Posts: 82
Registered: ‎01-10-2013
My Device: Bold 9900

Re: Thread not invoked in a Customized Field?

thanks for your suggestion, simon, i have been found the reason, the variable _animation_size only set value in layout() blcok once time
Please use plain text.
Developer
walkline
Posts: 82
Registered: ‎01-10-2013
My Device: Bold 9900

Re: Thread not invoked in a Customized Field?

Here is the correct code, FYI

import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.FontFamily;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiApplication;

public class BlockField extends Field
{
	private static Font _font;
	private static final int CORNER_RADIUS = 12;

	private int _value = 0;
	private int _fore_color = 0;
	private int _background_color = 0;
	private String _text = "";
	private int _animation_size = 0;
	private boolean _need_animation = false;

	public BlockField()
	{
		super(NON_FOCUSABLE);

		try {
			int fontSize = 7;
			FontFamily family = FontFamily.forName("Tahoma");

			if (Display.getWidth() > Display.getHeight())
			{
				if (Display.getWidth() > 480) {fontSize = 9;}	
			} else {
				if (Display.getHeight() >= 480) {fontSize = 9;}
			}

			_font = family.getFont(Font.EXTRA_BOLD, fontSize, Ui.UNITS_pt);
		} catch (ClassNotFoundException e) {}
	}

	public void clear()
	{
		setValue(0);
		invalidate();
	}

	public void setAnimationMode(boolean value) {_need_animation = value;}

	public int getValue() {return _value;}

	public void setValue(int value)
	{
		_value = value;
		_text = ((_value != 0) ? String.valueOf(value) : ""); 
		_fore_color = ((_value > 4) ? 0xf9f6f2 : 0x776e65);
		_animation_size = getWidth() / 3;

		setBackgroundColor();
	}

	public void setBackgroundColor()
	{
		switch (_value)
		{
			case 0:
				_background_color = 0xccc0b3;
				break;
			case 2:
				_background_color = 0xeee4da;
				break;
			case 4:
				_background_color = 0xeee0c8;
				break;
			case 8:
				_background_color = 0xf2b179;
				break;
			case 16:
				_background_color = 0xf59563;
				break;
			case 32:
				_background_color = 0xf67c5f;
				break;
			case 64:
				_background_color = 0xf65e3b;
				break;
			case 128:
				_background_color = 0xffedcf72;
				break;
			case 256: 
				_background_color = 0xffedcc61;
				break;
			case 512:
				_background_color = 0xffedc850;
				break;
			case 1024:
				_background_color = 0xffedc53f;
				break;
			case 2048:
				_background_color = 0xffedc22e;
				break;
			case 4096:
				_background_color = 0xff3c39;
				break;
		}
	}

	public synchronized void startAnimation()
	{
		new Thread()
		{
			public void run()
			{
				while (_animation_size < getWidth())
				{
					try {
	                	Thread.sleep(10);

						_animation_size += 10;
						if (_animation_size > getWidth()) {_animation_size = getWidth();}

						synchronized (UiApplication.getEventLock()) {doPaint();}
					} catch (InterruptedException e) {}
				}

				_need_animation = false;
			}
		}.start();
	}

	public synchronized void doPaint() {this.invalidate();}

	protected void layout(int width, int height) {setExtent(width, height);}

	protected void paint(Graphics g)
	{
		g.setColor(_fore_color);
		g.setFont(_font);
		g.drawText(_text, (getWidth() - _font.getAdvance(_text)) / 2, (getHeight() - _font.getHeight()) / 2);
	}

	protected void paintBackground(Graphics g)
	{
		g.setColor(_background_color);

		if (_need_animation)
		{
			g.fillRoundRect((getWidth() - _animation_size) / 2, (getHeight() - _animation_size) / 2, _animation_size, _animation_size, CORNER_RADIUS, CORNER_RADIUS);
		} else {
			g.fillRoundRect(0, 0, getWidth(), getHeight(), CORNER_RADIUS, CORNER_RADIUS);						
		}
	}
}

 

Please use plain text.