JavaFX Move image animation - animation

How would I move an image across an AnchorPane in JavaFX? The image should move itself over a period of time. So far I have: (view is the ImageView already in the AnchorPane)
position = 35.0;
for(int x = 0; x<11; x++){
TimeUnit.SECONDS.sleep(1);
myAnchorPane.getChildren().remove(view);
AnchorPane.setRightAnchor(view, position);
AnchorPane.setTopAnchor(view, 103.0);
myAnchorPane.getChildren().add(view);
position += 20;
}
within the initialize() method of my controller. However, this does not work since the stage appears with the image already moved.

Here is a class I create from an idea I got from tutoring a student.
You should use Javafx animation. This moves with button press, but if you
want to see the diver move right, just remove the code from inside the isRightPressed if-statement and place it outside the if-statement. Also, remove this part: * (Math.cos(Math.toRadians(rotation))).
import java.io.File;
import javafx.animation.AnimationTimer;
import javafx.event.EventHandler;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
/**
*
* #author blj0011
*/
public class Diver {
File diverFile;
ImageView ivDiver = new ImageView();
double rotation = 0.0;
boolean isUpPressed, isDownPressed, isLeftPressed, isRightPressed;
Diver()
{
diverFile = new File("src/img/diver.png");
if(diverFile.exists())
{
Image diverImage = new Image(diverFile.toURI().toString());
ivDiver.setImage(diverImage);
}
ivDiver.setFocusTraversable(true);
ivDiver.setOnKeyPressed(new EventHandler<KeyEvent>()
{
#Override
public void handle(KeyEvent event) {
switch(event.getCode()) {
case UP: isUpPressed = true; break;
case DOWN: isDownPressed = true; break;
case LEFT: isLeftPressed = true; break;
case RIGHT: isRightPressed = true; break;
}
}
});
ivDiver.setOnKeyReleased(new EventHandler<KeyEvent>()
{
#Override
public void handle(KeyEvent event) {
switch(event.getCode()) {
case UP: isUpPressed = false; break;
case DOWN: isDownPressed = false; break;
case LEFT: isLeftPressed = false; break;
case RIGHT: isRightPressed = false; break;
}
}
});
AnimationTimer timer = new AnimationTimer(){
#Override
public void handle(long now) {
if(isUpPressed){if(rotation == -360){rotation = 0;} ivDiver.setRotate(rotation+=5);}
if(isDownPressed){if(rotation == 360){rotation = 0;} ivDiver.setRotate(rotation-=5);}
if(isLeftPressed)
{
ivDiver.setX(ivDiver.getX() - 2.0 * (Math.cos(Math.toRadians(rotation))));
ivDiver.setY(ivDiver.getY() - 2.0 * (Math.sin(Math.toRadians(rotation))));
}
if(isRightPressed)
{
System.out.println("moving diver right!");
ivDiver.setX(ivDiver.getX() + 2.0 * (Math.cos(Math.toRadians(rotation))));
ivDiver.setY(ivDiver.getY() + 2.0 * (Math.sin(Math.toRadians(rotation))));
}
}
};
timer.start();
}
ImageView getDiver()
{
return ivDiver;
}
}
You code may look something like this.
AnimationTimer timer = new AnimationTimer(){
#Override
public void handle(long now) {
System.out.println("moving diver right!");
yourImageView.setX(yourImageView.getX() + 20.0 );
//yourImageView.setY(yourImageView.getY() + 20.0 );
}
};
timer.start();

Related

Animation flashing

I continuously have this problem with all my most recent animation projects. Every time I run my animations, they never seem to be completely visible and full, but rather they blink and flash similar to a light bulb that is not fully screwed in ( i know, strange comparison but I can't think of what else it resembles). I feel like it must have something to do with my placement of repaint(); but I'm just not sure at this point. On a previous animation I made, the problem was that my "private BufferedImage offScr" variable wasn't set correctly, but viewing other programs similar to the one I am working on now, I don't see why that variable would be necessary. Thanks for all your help folks, and I apologize for my lack of knowledge in programming vocabulary.
Here is my program so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
public class DoveAnimator extends JFrame implements ActionListener {
private int DELAY = 40; // the delay for the animation
private final int WIDTH = 400; // the window width
private final int HEIGHT = 180; // the window height
private final int IMAGEAMT = 8;
private Image [] doveLeft = new Image[IMAGEAMT];
private Image [] doveRight = new Image[IMAGEAMT];
private int doveIndex = 0;
private boolean isRight = true;
private JPanel dovePanel;
private Image dove;
private JButton slowerButton = new JButton ("Slower");
private JButton fasterButton = new JButton ("Faster");
private JButton reverseButton = new JButton ("Reverse");
private JButton pauseResumeButton = new JButton (" pause ");
private Timer timer;
private int clicks = 2;
private boolean pause = false;
/** The constructor */
public DoveAnimator() {
MediaTracker track = new MediaTracker(this);
for (int i = 0; i < IMAGEAMT; ++i) {
doveLeft[i] = new ImageIcon("doves/ldove" + (i+1) + ".gif").getImage();
doveRight[i] = new ImageIcon("doves/rdove" + (i+1) + ".gif").getImage();
track.addImage(doveLeft[i],0);
track.addImage(doveRight[i],0);
}
// dove = doveRight[0];
//track.addImage(bkgImage,0);
// track.addImage(dove,0);
try {
track.waitForAll();
} catch ( InterruptedException e ) { }
dove = doveRight[0];
JPanel mainPanel = new JPanel();
mainPanel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
setTitle ("Dove Animator");
dovePanel = new JPanel();
dovePanel.setPreferredSize(new Dimension(100, 125));
dovePanel.setBackground(Color.WHITE);
mainPanel.add(dovePanel);
JPanel buttonPanel = new JPanel();
buttonPanel.setPreferredSize(new Dimension(WIDTH, 40));
// button 1
slowerButton.addActionListener (this);
buttonPanel.add (slowerButton);
// button 2
fasterButton.addActionListener (this);
buttonPanel.add (fasterButton);
// button 3
reverseButton.addActionListener (this);
buttonPanel.add (reverseButton);
// button 4
pauseResumeButton.addActionListener (this);
buttonPanel.add (pauseResumeButton);
mainPanel.add(buttonPanel);
add(mainPanel);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
setVisible (true);
pack();
timer = new Timer(DELAY,this); // setting timer delay
timer.start(); // start the timer
}
public void switchDove() {
++doveIndex;
if (doveIndex >= IMAGEAMT)
doveIndex = 0;
if (isRight)
dove = doveRight[doveIndex];
else
dove = doveLeft[doveIndex];
dove = (isRight) ? doveRight[doveIndex] : doveLeft[doveIndex];
}
/** Handler for button clicks and timer events */
public void actionPerformed (ActionEvent evt) {
if (evt.getSource() == slowerButton)
{
DELAY += 10;
}
else if (evt.getSource() == reverseButton)
{
if(evt.getSource() == reverseButton && isRight == true){
isRight = false;
}
else if(evt.getSource() == reverseButton && !isRight){
isRight = true;
}
}
else if (evt.getSource() == fasterButton)
{
DELAY -= 10;
if (DELAY <= 10 ){
DELAY = 10;
}
}
else if (evt.getSource() == pauseResumeButton)
{
if(evt.getSource() == pauseResumeButton && !pause){
pauseResumeButton.setText(" Resume ");
timer.stop();
pause = true;
}
else if(evt.getSource() == pauseResumeButton && pause == true){
pauseResumeButton.setText(" Pause ");
timer.start();
pause = false;
}
}
else if (evt.getSource() == timer)
{
drawAnimation();
switchDove();
repaint();
}
}
/** Draws the dove in the dovePanel */
public void drawAnimation() {
Graphics page = dovePanel.getGraphics();
page.drawImage(dove,0,0,Color.WHITE,null);
}
/** The main method */
public static void main (String [] args) {
new DoveAnimator();
}
}
Yep it seems to be one of your repaint() calls. Take out your repaint() method call here:
else if (evt.getSource() == timer)
{
drawAnimation();
switchDove();
repaint();
It's confusing the program because you are already switching the doves. That's my best guess. I ran it and it seems to work though. Cheers!
Also I just noticed that the way you are adjusting your timer will yeild you no results. You need to use the command: timer.setDelay(newDelay); you can also put arguments in the parenthesis like timer.setDelay(DELAY -= 10);

gwt ClientBundle context.drawImage doesn't show image? my 2D engine

My code has not errors but I don't see the image. The image is located at the same place as the ClientBundle file is. Sorry for a chunk of code. In fact I am newbie in GWT (and in Java as well). And I teach myself. I made debugging and I saw the image was loaded, all classes was initialized, but the canvas was empty so far. I use NetBeans IDE 7.3.
I will be happy if somebody could give me any advice how to launch this code.
Thanks you upfront!
______ResourseInspector (nothing special)______________
The image is located at the same folder.
package info.alexpi.client.engine2D;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
public interface ResourseInspector extends ClientBundle {
public static final ResourseInspector INSTANCE = GWT.create(ResourseInspector.class);
#ClientBundle.Source("image1.png")
//GWT.getHostPageBaseURL() or GWT.getModuleBaseURL() - By the way, why it's not allowed to use here?
ImageResource Img();
}
_____Point2D____
package info.alexpi.client.engine2D;
public class Point2D {
public int x = 0;
public int y = 0;
}
___Rect2D____
package info.alexpi.client.engine2D;
public class Rect2D {
public int x;
public int y;
public int w;
public int h;
public Rect2D(){
x = 0;
y = 0;
w = 100;
h = 100;
}
public Rect2D(int x, int y, int w, int h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
}
______ImgElement2D_______
I need this class to keep width and high of the original image
package info.alexpi.client.engine2D;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.event.dom.client.ErrorEvent;
import com.google.gwt.event.dom.client.ErrorHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
public class ImgElement2D {
private Rect2D rect = new Rect2D();
private ImageElement imgElement;
private Image tempImg;
public ImgElement2D(String imgAddress){
try {
Image.prefetch(imgAddress);
tempImg = new Image(imgAddress);
// SafeUri fromString = UriUtils.fromString(imgAddress);
// tempImg.setUrl(fromString); //SafeUri url
// this method doesn't trigger
tempImg.addLoadHandler(new LoadHandler(){
#Override
public void onLoad(LoadEvent event) {
imgElement = (ImageElement) tempImg.getElement().cast();
rect.x = 0;
rect.y = 0;
rect.h = tempImg.getHeight();
rect.w = tempImg.getWidth();
//RootPanel.get().remove(image);
}
});
public ImgElement2D(ImageResource resource){
tempImg = new Image(resource);
rect.x = 0;
rect.y = 0;
rect.h = tempImg.getHeight();
rect.w = tempImg.getWidth();
imgElement = (ImageElement) tempImg.getElement().cast();
}
______Sprite2D_______
package info.alexpi.client.engine2D;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.dom.client.ImageElement;
public class Sprite2D {
private Point2D pos = new Point2D();
private ImgElement2D img;
private double scale;
private Rect2D rect = new Rect2D();
public Sprite2D(ImgElement2D image2D){
this.img = image2D;
this.rect = image2D.getRect();
this.scale = 1.0;
this.pos.x = 0;
this.pos.y = 0;
}
public void setImage(ImgElement2D image2D){
this.img = image2D;
}
public ImgElement2D getImgElement(){
return this.img;
}
________________DRAWING ______________________
public void draw(Context2d context){
ImageElement el = this.img.getImg();
if( el != null) {
context.drawImage(el, rect.x, rect.y,
rect.w, rect.h, pos.x, pos.y, rect.w*scale, rect.h*scale);
}
}
_____________Main entry point_________________
package info.alexpi.client;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.CssColor;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import info.alexpi.client.engine2D.ImgElement2D;
import info.alexpi.client.engine2D.Point2D;
import info.alexpi.client.engine2D.Rect2D;
import info.alexpi.client.engine2D.ResourseInspector;
import info.alexpi.client.engine2D.Sprite2D;
import java.util.ArrayList;
import java.util.List;
public class gwtEntryPoint implements EntryPoint {
static final String holderId = "canvasholder";
static final String upgradeMessage = "Your browser does not support the HTML5 Canvas. "
+ "Please upgrade your browser to view this demo.";
Canvas canvas;
Canvas backBuffer;
Context2d context;
Context2d backBufferContext;
final CssColor redrawColor = CssColor.make("rgba(255,255,255,0.0)");
// canvas size, in px
static final int height = 712;
static final int width = 800;
boolean isFirstLoading = true;
// mouse positions relative to canvas
int mouseX, mouseY;
//timer refresh rate, in milliseconds
static final int refreshRate = 25;
String imgAddress = GWT.getHostPageBaseURL() + "resources/images/Anthony-Catwalk-Dress.png";
//String imgAddress = "resources/images/image1.png"; //Second place of image
String cssAddress = GWT.getHostPageBaseURL() + "resources/myStyle.css";
double scale = 0.7;
List<Sprite2D> spriteList = new ArrayList<Sprite2D>();
ImgElement2D im;
public gwtEntryPoint() {
}
// init the canvases-------------------------------------------------------------------------
void initCanvas(){
canvas = Canvas.createIfSupported();
backBuffer = Canvas.createIfSupported();
if (canvas == null) {
RootPanel.get(holderId).add(new Label(upgradeMessage));
return;
}
canvas.setWidth(width + "px");
canvas.setHeight(height + "px");
canvas.setCoordinateSpaceWidth(width);
canvas.setCoordinateSpaceHeight(height);
backBuffer.setCoordinateSpaceWidth(width);
backBuffer.setCoordinateSpaceHeight(height);
canvas.setStyleName(cssAddress); //apply css style
canvas.getElement().getStyle().setProperty("border", "3px solid #00F");
RootPanel.get(holderId).add(canvas);
context = canvas.getContext2d();
backBufferContext = backBuffer.getContext2d();
}
// draw backBuffer ----------------------------------------------------------------------------
public void drawBuffer(Context2d back, Context2d front){
front.drawImage(back.getCanvas(), 0, 0);
}
void initElements(){
im = new ImgElement2D(ResourseInspector.INSTANCE.Img()); //ImageResource loading
Sprite2D sprite = new Sprite2D(im);
Rect2D r = new Rect2D(0,0, 228, 720); //man
sprite.setRect(r);
spriteList.add(sprite);
//im = new ImgElement2D(imgAddress); //another way of image loading (doesn't trigger)
sprite = new Sprite2D(im);
r = new Rect2D(226,12, 230, 283); //white T-shirt
sprite.setRect(r);
spriteList.add(sprite);
}
void doUpdate(){
// update the back canvas
backBufferContext.setFillStyle(redrawColor);
backBufferContext.fillRect(0, 0, width, height);
for(int x = 0; x < spriteList.size(); ++x){
spriteList.get(x).draw(backBufferContext);
// spriteList.get(x).draw(context);
}
drawBuffer(backBufferContext, context);
}
// init Assets & Timer -----------------------------------------------------------------------
void initAssets(){
initElements();
final Timer timer = new Timer() {
#Override
public void run() {
doUpdate();
}
};
timer.scheduleRepeating(refreshRate);
}
#Override
public void onModuleLoad() {
initCanvas();
initAssets();
}
}
See https://code.google.com/p/google-web-toolkit/issues/detail?id=8180
This is because, currently, new Image(imageResource) uses a blank GIF and puts the ImageResource as a background image. This is fixed in master and will ship in GWT 2.6 later this year.
The workaround is to use new Image(imageResource.getSafeUri()). It's not safe to do it in IE6/7 where a sprited image is used, but canvas is not supported there so it's not really an issue in this case (note that you could configure any permutation to use a sprited image rather than a data: URL, so technically it's not safe to use getSafeUri() in any browser; GWT 2.6 will add an isStandalone() method to tell you when it's safe to use it, and this is how new Image(imageResource) will be fixed)

GWT - Fading in/out a background image

I have a custom class as follows which works fine, the button grows/shrinks to accomodate the text and the bg image changes on a click.
Probem I want to solve is how to "fadeIN" one or other image when clicked/notClicked is called
Here is my code
public ExpandingOvalButton(String text) {
if (text.length() > 15) {
label.getElement().getStyle().setFontSize(20, Unit.PX);
} else {
label.getElement().getStyle().setFontSize(30, Unit.PX);
}
int width = 120;
initWidget(panel);
label.setText(text);
// width = width + (text.length() * 8);
String widthStr = width + "px";
image.setWidth(widthStr);
image.setHeight("100px");
button = new PushButton(image);
button.setWidth(widthStr);
button.setHeight("50px");
panel.add(button, 0, 0);
panel.add(label, 18, 14);
}
public void isClicked()
{
image.setUrl("images/rectangle_green.png");
}
public void unClicked()
{
image.setUrl("images/rectangle_blue.png");
}
#Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
return addDomHandler(handler, ClickEvent.getType());
}
public void setButtonEnabled(boolean enabled) {
// panel.setVisible(enabled);
// this.label.setVisible(enabled);
this.button.setVisible(enabled);
}
Here's a general utility class to fade any element:
public class ElementFader {
private int stepCount;
public ElementFader() {
this.stepCount = 0;
}
private void incrementStep() {
stepCount++;
}
private int getStepCount() {
return stepCount;
}
public void fade(final Element element, final float startOpacity, final float endOpacity, int totalTimeMillis) {
final int numberOfSteps = 30;
int stepLengthMillis = totalTimeMillis / numberOfSteps;
stepCount = 0;
final float deltaOpacity = (float) (endOpacity - startOpacity) / numberOfSteps;
Timer timer = new Timer() {
#Override
public void run() {
float opacity = startOpacity + (getStepCount() * deltaOpacity);
DOM.setStyleAttribute(element, "opacity", Float.toString(opacity));
incrementStep();
if (getStepCount() == numberOfSteps) {
DOM.setStyleAttribute(element, "opacity", Float.toString(endOpacity));
this.cancel();
}
}
};
timer.scheduleRepeating(stepLengthMillis);
}
}
Calling code for instance:
new ElementFader().fade(image.getElement(), 0, 1, 1000); // one-second fade-in
new ElementFader().fade(image.getElement(), 1, 0, 1000); // one-second fade-out
You could use GwtQuery. It provides fadeIn & fadeOut effects (and many other JQuery goodies), it is cross-browser compatible and seems to be pretty active.

viewpagerindicator and different layouts

i referred this code for viewpagerindicator from http://www.zylinc.com/blog-reader/items/viewpager-page-indicator.html .I want to display different views on different pages.Right now i m able to display list items on every page(3 pages) but i want to display lets say textview on second and third pages.i made some changes and created title using array here is the snippet for that
#Override
public String getTitle(int pos){
Log.i("FragmentList", "current page position is : " +mViewPager.getCurrentItem());
switch (pos) {
case 0:return titles[0];
case 1:return titles[1];
case 2:return titles[2];
default:return titles[0];
}
// pageListener = new DetailOnPageChange();
// mViewPager.setOnPageChangeListener(pageListener);
}
so when i change the page i also want to change the layouts i was thinking if i could get current position of the page i could put them in switch case and implement layout... but invain as mViewpager.getcurrentitem behaves properly in this function can some1 help me who should i implement that here is my code viewpagerindicator activty
package com.zylinc.view;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.zip.Inflater;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class ViewPagerIndicatorActivity extends FragmentActivity
{
DetailOnPageChange pageListener;
PagerAdapter mPagerAdapter;
static ViewPager mViewPager;
ViewPagerIndicator mIndicator;
static TextView stv;
static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
static SimpleDateFormat readableDateFormat = new SimpleDateFormat("yyyy - MM/dd");
public int numberofPages = 3;
Inflater inflater;
public static final String[] titles = new String[]{"First Page","Second Page","Third Page"};
public static int pos;
public int currentPageIs;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create our custom adapter to supply pages to the viewpager.
mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setAdapter(mPagerAdapter);
// Start at a custom position
mViewPager.setCurrentItem(0);
// Find the indicator from the layout
mIndicator = (ViewPagerIndicator)findViewById(R.id.indicator);
// Set the indicator as the pageChangeListener
mViewPager.setOnPageChangeListener(mIndicator);
// Initialize the indicator. We need some information here:
// * What page do we start on.
// * How many pages are there in total
// * A callback to get page titles
Log.i("number of counts are ", "pages are"+mPagerAdapter.getCount());
mIndicator.init(0, mPagerAdapter.getCount(), mPagerAdapter);
Resources res = getResources();
Drawable prev = res.getDrawable(R.drawable.indicator_prev_arrow);
Drawable next = res.getDrawable(R.drawable.indicator_next_arrow);
mIndicator.setFocusedTextColor(new int[]{255, 0, 0});
// Set images for previous and next arrows.
mIndicator.setArrows(prev, next);
mIndicator.setOnClickListener(new OnIndicatorClickListener());
}
class OnIndicatorClickListener implements ViewPagerIndicator.OnClickListener{
#Override
public void onCurrentClicked(View v) {
Toast.makeText(ViewPagerIndicatorActivity.this, "Hello", Toast.LENGTH_SHORT).show();
}
#Override
public void onNextClicked(View v) {
mViewPager.setCurrentItem(Math.min(mPagerAdapter.getCount() - 1, mIndicator.getCurrentPosition() + 1));
}
#Override
public void onPreviousClicked(View v) {
mViewPager.setCurrentItem(Math.max(0, mIndicator.getCurrentPosition() - 1));
}
}
class PagerAdapter extends FragmentPagerAdapter implements ViewPagerIndicator.PageInfoProvider
{
ArrayList<Fragment> fragments = new ArrayList<Fragment>();
//ArrayList<String> showTitles = new ArrayList<String>();
//String myPos = titles[pos];
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, pos - getCount() / 2);
return ItemFragment.newInstance(cal.getTime());
//return ItemFragment.newInstance(titles[pos]);
}
#Override
public String getTitle(int pos){
Log.i("FragmentList", "current page position is : " +mViewPager.getCurrentItem());
switch (pos) {
case 0:return titles[0];
case 1:return titles[1];
case 2:return titles[2];
default:return titles[0];
}
// pageListener = new DetailOnPageChange();
// mViewPager.setOnPageChangeListener(pageListener);
}
#Override
public int getCount() {
return numberofPages;
}
}
public class DetailOnPageChange extends ViewPager.SimpleOnPageChangeListener{
#Override
public void onPageSelected(int position) {
Log.i("FragmentList", "************* position is : " +currentPageIs);
currentPageIs = position;
}
public int getCurrentPage(){
return currentPageIs;
}
}
public static class ItemFragment extends ListFragment
{
static Date date;
TextView tv;
static ItemFragment newInstance(Date date) {
ItemFragment f = new ItemFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putString("date", sdf.format(date));
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
this.date = sdf.parse(getArguments().getString("date"));
} catch (ParseException e) {
e.printStackTrace();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Log.i("FragmentList", "current page checker position is : " +titles[pos]);
View v = inflater.inflate(R.layout.date_fragment, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText(readableDateFormat.format(date));
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, list));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
public static final String[] list = new String[]{"France", "London", "Sweden", "Denmark", "Germany", "Finland", "Thailand", "Taiwan", "USA", "Norway", "Lithuania", "Bosnia", "Russia", "Vietnam", "Australia"};
}
and here is adapter
package com.zylinc.view;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* An small bar indicating the title of the previous,
* current and next page to be shown in a ViewPager.
* Made to resemble the indicator in the Google+ application
* in function.
*
* #author Mark Gjøl # Zylinc
*/
public class ViewPagerIndicator extends RelativeLayout implements OnPageChangeListener {
private static final int PADDING = 5;
TextView mPrevious;
TextView mCurrent;
TextView mNext;
int mCurItem;
int mRestoreCurItem = -1;
LinearLayout mPreviousGroup;
LinearLayout mNextGroup;
int mArrowPadding;
int mSize;
ImageView mCurrentIndicator;
ImageView mPrevArrow;
ImageView mNextArrow;
int[] mFocusedTextColor;
int[] mUnfocusedTextColor;
OnClickListener mOnClickHandler;
public interface PageInfoProvider{
String getTitle(int pos);
}
public interface OnClickListener{
void onNextClicked(View v);
void onPreviousClicked(View v);
void onCurrentClicked(View v);
}
public void setOnClickListener(OnClickListener handler){
this.mOnClickHandler = handler;
mPreviousGroup.setOnClickListener(new OnPreviousClickedListener());
mCurrent.setOnClickListener(new OnCurrentClickedListener());
mNextGroup.setOnClickListener(new OnNextClickedListener());
}
public int getCurrentPosition(){
return mCurItem;
}
PageInfoProvider mPageInfoProvider;
public void setPageInfoProvider(PageInfoProvider pageInfoProvider){
this.mPageInfoProvider = pageInfoProvider;
}
public void setFocusedTextColor(int[] col){
System.arraycopy(col, 0, mFocusedTextColor, 0, 3);
updateColor(0);
}
public void setUnfocusedTextColor(int[] col){
System.arraycopy(col, 0, mUnfocusedTextColor, 0, 3);
mNext.setTextColor(Color.argb(255, col[0], col[1], col[2]));
mPrevious.setTextColor(Color.argb(255, col[0], col[1], col[2]));
updateColor(0);
}
#Override
protected Parcelable onSaveInstanceState() {
Parcelable state = super.onSaveInstanceState();
Bundle b = new Bundle();
b.putInt("current", this.mCurItem);
b.putParcelable("viewstate", state);
return b;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(((Bundle)state).getParcelable("viewstate"));
mCurItem = ((Bundle)state).getInt("current", mCurItem);
this.setText(mCurItem - 1);
this.updateArrows(mCurItem);
this.invalidate();
}
/**
* Initialization
*
* #param startPos The initially selected element in the ViewPager
* #param size Total amount of elements in the ViewPager
* #param pageInfoProvider Interface that returns page titles
*/
public void init(int startPos, int size, PageInfoProvider pageInfoProvider){
setPageInfoProvider(pageInfoProvider);
this.mSize = size;
setText(startPos - 1);
mCurItem = startPos;
}
public ViewPagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
addContent();
}
public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
addContent();
}
public ViewPagerIndicator(Context context) {
super(context);
addContent();
}
/**
* Add drawables for arrows
*
* #param prev Left pointing arrow
* #param next Right pointing arrow
*/
public void setArrows(Drawable prev, Drawable next){
this.mPrevArrow = new ImageView(getContext());
this.mPrevArrow.setImageDrawable(prev);
this.mNextArrow = new ImageView(getContext());
this.mNextArrow.setImageDrawable(next);
LinearLayout.LayoutParams arrowLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
arrowLayoutParams.gravity = Gravity.CENTER;
mPreviousGroup.removeAllViews();
mPreviousGroup.addView(mPrevArrow, arrowLayoutParams);
mPreviousGroup.addView(mPrevious, arrowLayoutParams);
mPrevious.setPadding(PADDING, 0, 0, 0);
mNext.setPadding(0, 0, PADDING, 0);
mArrowPadding = PADDING + prev.getIntrinsicWidth();
mNextGroup.addView(mNextArrow, arrowLayoutParams);
updateArrows(mCurItem);
}
/**
* Create all views, build the layout
*/
private void addContent(){
mFocusedTextColor = new int[]{0, 0, 0};
mUnfocusedTextColor = new int[]{190, 190, 190};
// Text views
mPrevious = new TextView(getContext());
mCurrent = new TextView(getContext());
mNext = new TextView(getContext());
RelativeLayout.LayoutParams previousParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
previousParams.addRule(RelativeLayout.ALIGN_LEFT);
RelativeLayout.LayoutParams currentParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
currentParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
RelativeLayout.LayoutParams nextParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
nextParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
// Groups holding text and arrows
mPreviousGroup = new LinearLayout(getContext());
mPreviousGroup.setOrientation(LinearLayout.HORIZONTAL);
mNextGroup = new LinearLayout(getContext());
mNextGroup.setOrientation(LinearLayout.HORIZONTAL);
mPreviousGroup.addView(mPrevious, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mNextGroup.addView(mNext, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
addView(mPreviousGroup, previousParams);
addView(mCurrent, currentParams);
addView(mNextGroup, nextParams);
mPrevious.setSingleLine();
mCurrent.setSingleLine();
mNext.setSingleLine();
mPrevious.setText("previous");
mCurrent.setText("current");
mNext.setText("next");
mPrevious.setClickable(false);
mNext.setClickable(false);
mCurrent.setClickable(true);
mPreviousGroup.setClickable(true);
mNextGroup.setClickable(true);
// Set colors
mNext.setTextColor(Color.argb(255, mUnfocusedTextColor[0], mUnfocusedTextColor[1], mUnfocusedTextColor[2]));
mPrevious.setTextColor(Color.argb(255, mUnfocusedTextColor[0], mUnfocusedTextColor[1], mUnfocusedTextColor[2]));
updateColor(0);
}
#Override
public void onPageScrollStateChanged(int state) {
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
positionOffsetPixels = adjustOffset(positionOffsetPixels);
position = updatePosition(position, positionOffsetPixels);
setText(position - 1);
updateColor(positionOffsetPixels);
updateArrows(position);
updatePositions(positionOffsetPixels);
mCurItem = position;
}
void updatePositions(int positionOffsetPixels){
int textWidth = mCurrent.getWidth() - mCurrent.getPaddingLeft() - mCurrent.getPaddingRight();
int maxOffset = this.getWidth() / 2 - textWidth / 2 - mArrowPadding;
if(positionOffsetPixels > 0){
maxOffset -= this.getPaddingLeft();
int offset = Math.min(positionOffsetPixels, maxOffset - 1);
mCurrent.setPadding(0, 0, 2 * offset, 0);
// Move previous text out of the way. Slightly buggy.
/*
int overlapLeft = mPreviousGroup.getRight() - mCurrent.getLeft() + mArrowPadding;
mPreviousGroup.setPadding(0, 0, Math.max(0, overlapLeft), 0);
mNextGroup.setPadding(0, 0, 0, 0);
*/
}else{
maxOffset -= this.getPaddingRight();
int offset = Math.max(positionOffsetPixels, -maxOffset);
mCurrent.setPadding(-2 * offset, 0, 0, 0);
// Move next text out of the way. Slightly buggy.
/*
int overlapRight = mCurrent.getRight() - mNextGroup.getLeft() + mArrowPadding;
mNextGroup.setPadding(Math.max(0, overlapRight), 0, 0, 0);
mPreviousGroup.setPadding(0, 0, 0, 0);
*/
}
}
/**
* Hide arrows if we can't scroll further
*
* #param position
*/
void updateArrows(int position){
if(mPrevArrow != null){
mPrevArrow.setVisibility(position == 0 ? View.INVISIBLE : View.VISIBLE);
mNextArrow.setVisibility(position == mSize - 1 ? View.INVISIBLE : View.VISIBLE);
}
}
/**
* Adjust position to be the view that is showing the most.
*
* #param givenPosition
* #param offset
* #return
*/
int updatePosition(int givenPosition, int offset){
int pos;
if(offset < 0){
pos = givenPosition + 1;
}else{
pos = givenPosition;
}
return pos;
}
/**
* Fade "currently showing" color depending on it's position
*
* #param offset
*/
void updateColor(int offset){
offset = Math.abs(offset);
// Initial condition: offset is always 0, this.getWidth is also 0! 0/0 = NaN
int width = this.getWidth();
float fraction = width == 0 ? 0 : offset / ((float)width / 4.0f);
fraction = Math.min(1, fraction);
int r = (int)(mUnfocusedTextColor[0] * fraction + mFocusedTextColor[0] * (1 - fraction));
int g = (int)(mUnfocusedTextColor[1] * fraction + mFocusedTextColor[1] * (1 - fraction));
int b = (int)(mUnfocusedTextColor[2] * fraction + mFocusedTextColor[2] * (1 - fraction));
mCurrent.setTextColor(Color.argb(255, r, g, b));
}
/**
* Update text depending on it's position
*
* #param prevPos
*/
void setText(int prevPos){
if(prevPos < 0){
mPrevious.setText("");
}else{
mPrevious.setText(mPageInfoProvider.getTitle(prevPos));
}
mCurrent.setText(mPageInfoProvider.getTitle(prevPos + 1));
if(prevPos + 2 == this.mSize){
mNext.setText("");
}else{
mNext.setText(mPageInfoProvider.getTitle(prevPos + 2));
}
}
// Original:
// 244, 245, 0, 1, 2
// New:
// -2, -1, 0, 1, 2
int adjustOffset(int positionOffsetPixels){
// Move offset half width
positionOffsetPixels += this.getWidth() / 2;
// Clamp to width
positionOffsetPixels %= this.getWidth();
// Center around zero
positionOffsetPixels -= this.getWidth() / 2;
return positionOffsetPixels;
}
#Override
public void onPageSelected(int position) {
// Reset padding when the page is finally selected (May not be necessary)
mCurrent.setPadding(0, 0, 0, 0);
}
class OnPreviousClickedListener implements android.view.View.OnClickListener{
#Override
public void onClick(View v) {
if(mOnClickHandler != null){
mOnClickHandler.onPreviousClicked(ViewPagerIndicator.this);
}
}
}
class OnCurrentClickedListener implements android.view.View.OnClickListener{
#Override
public void onClick(View v) {
if(mOnClickHandler != null){
mOnClickHandler.onCurrentClicked(ViewPagerIndicator.this);
}
}
}
class OnNextClickedListener implements android.view.View.OnClickListener{
#Override
public void onClick(View v) {
if(mOnClickHandler != null){
mOnClickHandler.onNextClicked(ViewPagerIndicator.this);
}
}
}
}
You may find this blog useful; Making ActionBarSherlock and ViewPagerIndicator play nice
You may also come across a bug mentioned here; Android - SupportMapFragment with GoogleMaps API 2.0 giving IllegalArgumentException
Good Luck..!!

blackberry: AbsoluteFieldManager dont show custom fields

I'm trying to make a menu with an absolute layout that contains custom items extending Field. This items show well in the HorizontalFieldManager for example, but with the AbsoluteFieldManager it just shows a blank screen.
This is my code so far:
/********************
* CustomField.java *
********************/
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Keypad;
public class CustomField extends Field {
Bitmap img;
String s1, s2;
Font font;
int textColorUnfocused, textColorFocused, bgColorUnfocused, bgColorFocused;
public CustomField(long style) {
super(style);
}
public CustomField(Bitmap img, String s1, String s2) {// , long style) {
// super(style);
this.img = img;
this.s1 = s1;
this.s2 = s2;
this.font = Font.getDefault();
textColorUnfocused = 0x000000;
textColorFocused = 0xffffff;
bgColorUnfocused = 0xffffff;
bgColorFocused = 0x3956F7;
}
protected void layout(int maxWidth, int maxHeight) {
Font font = getFont();
int width = img.getWidth() + 10;
int height = img.getHeight() + (font.getHeight() * 3);
setExtent(Math.min(width, maxWidth), Math.min(height, maxHeight));
}
protected void onFocus(int direction) {
super.onFocus(direction);
invalidate();
}
protected void onUnfocus() {
super.onUnfocus();
invalidate();
}
public boolean isFocusable() {
return true;
}
protected void paint(Graphics g) {
// Draw background
g.setColor(isFocus() ? bgColorFocused : bgColorUnfocused);
g.fillRect(0, 0, getWidth(), getHeight());
// draw image
g.drawBitmap(5, 5, img.getWidth(), img.getHeight(), img, 0, 0);
g.setColor(isFocus() ? textColorFocused : textColorUnfocused);
// draw text
g.drawText(s1, ((img.getWidth() + 10) / 2) - (font.getAdvance(s1) / 2),
img.getHeight() + font.getHeight());
g.drawText(s2, ((img.getWidth() + 10) / 2) - (font.getAdvance(s2) / 2),
img.getHeight() + (2 * font.getHeight()));
}
protected boolean keyChar(char character, int status, int time) {
if (character == Keypad.KEY_ENTER) {
fieldChangeNotify(0);
return true;
}
return super.keyChar(character, status, time);
}
public int getY() {
return img.getHeight() + (font.getHeight() * 3);
}
public int getX() {
return img.getWidth();
}
}
/**************
* MyApp.java *
**************/
import net.rim.device.api.ui.UiApplication;
public class MyApp extends UiApplication{
public static void main(String args[]){
MyApp theApp = new MyApp();
theApp.enterEventDispatcher();
}
public MyApp()
{
// Push a screen onto the UI stack for rendering.
pushScreen(new MyScreen());
}
}
/*****************
* MyScreen.java *
*****************/
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.container.AbsoluteFieldManager;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
public class MyScreen extends MainScreen {
public MyScreen() {
AbsoluteFieldManager manager = new AbsoluteFieldManager();
Bitmap img = Bitmap.getBitmapResource("1.png");
CustomField cf1 = new CustomField(img, "an", "Item");
CustomField cf2 = new CustomField(img, "another", "Item");
manager.add(cf1, 10, 10);
manager.add(cf2, 150, 150);
//HorizontalFieldManager hfm = new HorizontalFieldManager(
// Manager.HORIZONTAL_SCROLL);
//hfm.add(cf1); hfm.add(cf2);
//add(hfm);
add(manager);
}
}
And the image (1.png) http://www7.pic-upload.de/14.05.11/rhr4jcfuy9f8.png
How can I get the absolute manager to show my custom field?
My guess is that maybe AbsoluteFieldManager is passing 0, 0 to the layout method of your custom field. So your logic in there is calling setExtent(0, 0).

Resources