JavaFX Animation Error When Transitioning Control - animation

I am trying to transition a JavaFX control using PathTransition. In execution, the control moves erratically (I made it work for a Rectangle).
The attached sample attempts to move a Label from one position to another based on the positions of two other labels. The label immediately jumps to a point below its presumed starting point, and then transitions to another spot below its intended target location.
Debug info indicates that the label is starting at (50, 50) with an offset of (0, 0), aiming for a new location of (200, 50). When the animation completes I believe it should be at position (50, 50) with an offset of (150, 0); in fact, it has a location of (50, 50) with an offset of (148, 38.5).
What am I doing wrong?
Thanks for the help.
package fxsort;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.shape.ArcTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Test4
extends Application
{
private final Label statLabel1 =
getLabel( "Jehosaphat", 50, 50, Color.gray( .85 ) );
private final Label statLabel2 =
getLabel( "Jehosaphat", 200, 50, Color.gray( .85 ) );
private final Label periLabel =
getLabel( "Jehosaphat", 50, 50, Color.RED );
public static void main(String[] args)
{
launch( args );
}
#Override
public void start(Stage stage) throws Exception
{
Button start = new Button( "Start" );
start.relocate( 250, 125 );
start.setOnAction(
new EventHandler<ActionEvent>()
{
#Override
public void handle( ActionEvent evt )
{
PathTransition transition = getTransition();
transition.play();
}
}
);
Group root =
new Group( statLabel1, statLabel2, periLabel, start );
stage.setScene( new Scene( root, 350, 200 ) ) ;
stage.show();
}
private Label
getLabel( String text, double xco, double yco, Color color )
{
Label label = new Label( text );
label.relocate( xco, yco );
label.setTextFill( color );
label.setFont( Font.font( "Arial", 20 ) );
return label;
}
private PathTransition
getTransition()
{
Label from = statLabel1;
Label too = statLabel2;
Duration duration = Duration.millis( 3000 );
double startX = from.getLayoutX();// + 30;
double startY = from.getLayoutY();// + 30;
System.out.println( "From Layout: " + startX + ", " + startY );
System.out.println( "From Offset: " + from.getTranslateX()
+ ", " + from.getTranslateX() );
double endX = too.getLayoutX();// + 30;
double endY = too.getLayoutY();// + 30;
System.out.println( "To Layout: " + endX + ", " + endY );
System.out.println( "To Offset: " + too.getTranslateX()
+ ", " + too.getTranslateX() );
MoveTo start = new MoveTo( startX, startY );
System.out.println( "MoveTo: " + start.getX() + ", " + start.getY() );
ArcTo end = new ArcTo();
end.setX( endX );
end.setY( endY );
end.setRadiusX( 100 );
end.setRadiusY( 100 );
System.out.println( "ArcTo: " + end.getX() + ", " + end.getY() );
System.out.println( "**********" );
Path path = new Path();
path.getElements().addAll( start, end );
PathTransition transition = new PathTransition();
transition.setDuration( duration );
transition.setPath( path );
transition.setNode( periLabel );
transition.setOnFinished(
new EventHandler<ActionEvent>()
{
public void handle( ActionEvent evt )
{
System.out.println( "Landed: " + periLabel.getLayoutX()
+ ", " + periLabel.getLayoutY() );
System.out.println( "Offset: " + periLabel.getTranslateX()
+ ", " + periLabel.getTranslateY() );
}
}
);
return transition;
}
}

There are two issues with you code:
PathTransition moves Node in it's own coordinate system. So if your node has layoutX/Y set to 50,50 as periLabel does -- it will be shifted.
PathTransition moves Node by Node's center, not by top-left corner.
Next code will fix your problems:
private PathTransition getTransition() {
Label from = statLabel1;
Label too = statLabel2;
Duration duration = Duration.millis(3000);
// fix problem (1)
periLabel.relocate(0, 0);
// fix problem (2)
double startX = from.getLayoutX() + from.getBoundsInLocal().getWidth() / 2;
double startY = from.getLayoutY() + from.getBoundsInLocal().getHeight() / 2;
double endX = too.getLayoutX() + too.getBoundsInLocal().getWidth() / 2;
double endY = too.getLayoutY() + too.getBoundsInLocal().getHeight() / 2;

Related

Implementing circle progress bar in libGDX

I want to create a circle progress bar, that will look like this using libgdx library. For now on I've created simple horizontal progressbar using different Images as layers overlapping themselfs and one of them resizing to simulate progress. I found this example, how to draw circle progress bar, but I don't understand how to use this implementation and how can I handle it. The textureRegion in constructor is the progress indicator? and I could not find the method responsible to set the actual progress.
EDIT: I've made my solution basic on this implementation. I put 3 layers which overlapping themselfs and whenever the middle layer swipe's the progress is showed. But Ive have a problem: whenever I try to resize my ProgressCircle instance it move down below the background layer.
public class ProgressCircle extends Image {
public enum IntersectAt {
NONE, TOP, BOTTOM, LEFT, RIGHT;
}
TextureRegion texture;
PolygonSpriteBatch polyBatch;
Vector2 center;
Vector2 centerTop;
Vector2 leftTop;
Vector2 leftBottom;
Vector2 rightBottom;
Vector2 rightTop;
Vector2 progressPoint;
float[] fv;
IntersectAt intersectAt;
private float PROGRESS_WIDTH=0f;
private float PROGRESS_HEIGHT=0f;
private float posX,posY;
public ProgressCircle(TextureRegion region, PolygonSpriteBatch polyBatch,float width,float height,float posX,float posY) {
super(region);
PROGRESS_WIDTH=width;
PROGRESS_HEIGHT=height;
this.posX=posX;
this.posY=posY;
this.texture = region;
this.polyBatch = polyBatch;
center = new Vector2(this.getWidth() / 2, this.getHeight() / 2);
centerTop = new Vector2(this.getWidth() / 2, this.getHeight());
leftTop = new Vector2(0, this.getHeight());
leftBottom = new Vector2(0, 0);
rightBottom = new Vector2(this.getWidth(), 0);
rightTop = new Vector2(this.getWidth(), this.getHeight());
progressPoint = new Vector2(this.getWidth() / 2, this.getHeight() / 2);
setPercentage(0);
}
private Vector2 IntersectPoint(Vector2 line) {
Vector2 v = new Vector2();
boolean isIntersect;
//check top
isIntersect = Intersector.intersectSegments(leftTop, rightTop, center, line, v);
//check bottom
if (isIntersect) {
intersectAt = IntersectAt.TOP;
return v;
} else
isIntersect = Intersector.intersectSegments(leftBottom, rightBottom, center, line, v);
//check left
if (isIntersect) {
intersectAt = IntersectAt.BOTTOM;
return v;
} else isIntersect = Intersector.intersectSegments(leftTop, leftBottom, center, line, v);
//check bottom
if (isIntersect) {
intersectAt = IntersectAt.LEFT;
return v;
} else isIntersect = Intersector.intersectSegments(rightTop, rightBottom, center, line, v);
if (isIntersect) {
intersectAt = IntersectAt.RIGHT;
return v;
} else {
intersectAt = IntersectAt.NONE;
return null;
}
}
public void setPercentage(float percent) {
//100 % = 360 degree
float angle = convertToRadians(90);
angle -= convertToRadians(percent * 360 / 100);
float len = this.getWidth() > this.getHeight() ? this.getWidth() : this.getHeight();
float dy = (float) (Math.sin(angle) * len);
float dx = (float) (Math.cos(angle) * len);
Vector2 line = new Vector2(center.x + dx, center.y + dy);
Vector2 v = IntersectPoint(line);
if (intersectAt == IntersectAt.TOP) {
if (v.x >= this.getWidth() / 2) {
fv = new float[]{
center.x,
center.y,
centerTop.x,
centerTop.y,
leftTop.x,
leftTop.y,
leftBottom.x,
leftBottom.y,
rightBottom.x,
rightBottom.y,
rightTop.x,
rightTop.y,
v.x,
v.y
};
} else {
fv = new float[]{
center.x,
center.y,
centerTop.x,
centerTop.y,
v.x,
v.y
};
}
} else if (intersectAt == IntersectAt.BOTTOM) {
fv = new float[]{
center.x,
center.y,
centerTop.x,
centerTop.y,
leftTop.x,
leftTop.y,
leftBottom.x,
leftBottom.y,
v.x,
v.y
};
} else if (intersectAt == IntersectAt.LEFT) {
fv = new float[]{
center.x,
center.y,
centerTop.x,
centerTop.y,
leftTop.x,
leftTop.y,
v.x,
v.y
};
} else if (intersectAt == IntersectAt.RIGHT) {
fv = new float[]{
center.x,
center.y,
centerTop.x,
centerTop.y,
leftTop.x,
leftTop.y,
leftBottom.x,
leftBottom.y,
rightBottom.x,
rightBottom.y,
v.x,
v.y
};
} else // if (intersectAt == IntersectAt.NONE)
{
fv = null;
}
}
#Override
public void draw(Batch batch, float parentAlpha) {
if (fv == null) return;
batch.end();
drawMe();
batch.begin();
}
public void drawMe() {
EarClippingTriangulator e = new EarClippingTriangulator();
ShortArray sv = e.computeTriangles(fv);
PolygonRegion polyReg = new PolygonRegion(texture, fv, sv.toArray());
PolygonSprite poly = new PolygonSprite(polyReg);
poly.setSize(PROGRESS_WIDTH,PROGRESS_HEIGHT);
poly.setPosition(posX,posY);
poly.setOrigin(poly.getOriginX(), poly.getOriginY());
poly.setRotation(this.getRotation());
poly.setColor(Color.GREEN);
polyBatch.begin();
poly.draw(polyBatch);
polyBatch.end();
}
float convertToDegrees(float angleInRadians) {
float angleInDegrees = angleInRadians * 57.2957795f;
return angleInDegrees;
}
float convertToRadians(float angleInDegrees) {
float angleInRadians = angleInDegrees * 0.0174532925f;
return angleInRadians;
}
}
and my init function:
ProgressCircle sprite;
private void initCircleProgress() {
Group group = new Group();
Image downBackground = new Image(atlas.findRegion("progressBackground"));
downBackground.setColor(Color.BLUE);
downBackground.setSize(USER_SCREEN_SIZE_WIDTH/5,USER_SCREEN_SIZE_WIDTH/5);
downBackground.setPosition(10,USER_SCREEN_SIZE_HEIGHT-(2*downBackground.getHeight()+20));
sprite = new ProgressCircle(atlas.findRegion("progressBackground"), pbatch,
downBackground.getWidth(),downBackground.getHeight(),downBackground.getX(),downBackground.getY());
sprite.setSize(downBackground.getWidth(),downBackground.getHeight());
sprite.setSize(downBackground.getX(),downBackground.getY());
Image label = new Image(atlas.findRegion("progressBackground"));
label.setSize(downBackground.getWidth()*0.8f,downBackground.getHeight()*0.8f);
label.setPosition(downBackground.getX()+(downBackground.getWidth()-label.getWidth())/2,
downBackground.getY()+(downBackground.getHeight()-label.getHeight())/2);
label.setColor(Color.WHITE);
group.addActor(downBackground);
group.addActor(sprite);
group.addActor(label);
group.setPosition(10,GAME_SIZE_HEIGHT-(group.getHeight()+20));
stage.addActor(group);
}
You need a circular gradient to mask out the desired parts.
Incrementing the masking values over time will result in a circular motion.
As you can see in the link to masking there are several methods to achieve this. A stencil buffer would be a good choice but can result in jaggy edges. Writing your own shader would be perfect but kinda hard if you never wrote a shader. You can also try to parse both pix maps and decide what pixels to draw while looping through both pixmaps. If the masking image and your source have equal texture space you can do this in one loop so it would not be that much slower then a shader and whatever works for you is a good solution, you can always optimize later.

Drools 6.5 Final CEP (Fusion) stability and performance problems

I am trying to see the max EPS capacity of Drools CEP. I am using 8 core 2.6 GHz CPU with 16 GB RAM. I am testing just 200 EPS with 2 rules. Drools starts good but later (within 5 to 15 minutes) it stucks or starts NOT TO FIRE
I have tested with fireAllRules and fireUntilHalt.
My Test Code:
package com.anet.correlation;
public class TestRealCase {
public static void main(String[] args) {
Main.initTest();
RulesRegistery.starttime = System.currentTimeMillis();
if (RuleRunTimeRegistery.isFireuntilHalt) {
Thread t = new Thread(new FT());
t.start();
}
int i = 0;
if (Main.ruleEngine != null) {
while (true) {
GeneralCorrelationObject ao1 = new GeneralCorrelationObject();
ao1.setLOGTYPE("Firewalls");
ao1.setSourceMachine("1.2.3.4" + (i % 500));
ao1.setDestinationPort(i);
Main.ruleEngine.evaluate(ao1);
i++;
if (i % RulesRegistery.EPS == 0)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
My DRL File
import com.anet.correlation.*;
import java.util.*;
import com.anet.ntLog.collector.*;
import com.anet.alarm.*;
import com.anet.util.*;
import com.anet.correlation.operators.*;
import com.anet.correlation.utils.*;
declare GeneralCorrelationObject
#role(event)
#expires( 1200s )
end
rule "Port Scan_Port Scan_16"
salience 0
no-loop
when
$map1: Map()
from accumulate(
generalcorrelationobject1:GeneralCorrelationObject(LOGTYPE=='Firewalls') over window:time( 1m )
,init( Map m = new HashMap();Hashtable ht= new Hashtable(); ),
action(
if(generalcorrelationobject1.getSourceMachine()==null)
{
return;
}
String key="SourceMachine="+generalcorrelationobject1.getSourceMachine();
List list = (List)m.get(key);
if( list == null )
list = new ArrayList();
Object val1=generalcorrelationobject1.getDestinationPort();
String value1;
if (val1 instanceof Integer)
value1=val1+"";
else
value1=(String)val1;
String not_key=value1;
if (ht.containsKey(key)){
Hashtable ht_hash=(Hashtable)ht.get(key);
Object ht_val=ht_hash.get(not_key);
String ht_value;
if (ht_val instanceof Integer)
ht_value=ht_val+"";
else
ht_value=(String)ht_val;
if (!not_key.equalsIgnoreCase(ht_value)){
ht_hash.put(not_key, not_key);
ht.put(key, ht_hash);
list.add( generalcorrelationobject1 );
}
}
else{
Hashtable ht_hash=new Hashtable();
ht_hash.put(not_key, not_key);
ht.put(key, ht_hash);
list.add( generalcorrelationobject1 );
}
m.put(key,list);),
result( m )
)
then
/*
if ((new CheckListSize()).check($map1,10)){
System.out.println("Done");
}
*/
Iterator s = $map1.keySet().iterator();
while (s.hasNext()) {
String key = (String) s.next();
List list = (List) $map1.get(key);
System.out.println(key+" : "+list.size());
}
end
rule "Port eee Scan_161"
salience 100
no-loop
when
ee:GeneralCorrelationObject()
then
if (RulesRegistery.numberofsingleruleexecution % RulesRegistery.printEPS == 0) {
System.out.println(ee.getSourceMachine());
}
RulesRegistery.numberofsingleruleexecution++;
end
RuleEngine Code
package com.anet.correlation;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;
import org.kie.api.KieBase;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.internal.builder.conf.RuleEngineOption;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.api.io.ResourceType;
public final class RulesEngine {
KieSession ksession;
KieBuilder kbuilder;
public static String header = null;
public RulesEngine(boolean b) {
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem();
kfs.write("src/main/resources/bench.drl", getRule());
this.kbuilder = ks.newKieBuilder(kfs);
this.kbuilder.buildAll();
if (this.kbuilder.getResults().hasMessages(new Message.Level[] { Message.Level.ERROR })) {
throw new IllegalArgumentException(this.kbuilder.getResults().toString());
}
ReleaseId relId = this.kbuilder.getKieModule().getReleaseId();
KieContainer kcontainer = ks.newKieContainer(relId);
KieBaseConfiguration kbconf = ks.newKieBaseConfiguration();
kbconf.setOption(EventProcessingOption.STREAM);
kbconf.setOption(RuleEngineOption.PHREAK);
// kbconf.setOption(RuleEngineOption.RETEOO);
System.out.println("KB " + kbconf.getProperty("drools.ruleEngine"));
KieBase kbase = kcontainer.newKieBase(kbconf);
KieSessionConfiguration ksconf = ks.newKieSessionConfiguration();
this.ksession = kbase.newKieSession(ksconf, null);
}
String readFile(String fileName) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append("\n");
line = br.readLine();
}
String rule = (sb.toString());
System.out.println("New Final");
System.out.println(rule);
return rule;
} finally {
br.close();
}
}
public String getRule() {
try {
return readFile(".." + File.separator + "rules" + File.separator + "all.drl");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void evaluate(GeneralCorrelationObject message) {
if (message == null) {
System.out.println("message null ");
return;
}
if (ksession == null) {
System.out.println("ksession null ");
return;
}
try {
Long n = System.currentTimeMillis();
if (RulesRegistery.numberofrules % RulesRegistery.printEPS == 0) {
System.out.println("Inserting Objects " + RulesRegistery.numberofrules + " EPS : "
+ (RulesRegistery.numberofrules / ((n - RulesRegistery.starttime) / 1000)) + " : Total time "
+ ((n - RulesRegistery.starttime) / (1000 * 60)) + " : " + new Date());
}
ksession.insert(message);
if (RulesRegistery.numberofrules % RulesRegistery.printEPS == 0) {
System.out.println("Inserted Objects " + RulesRegistery.numberofrules + " EPS : "
+ (RulesRegistery.numberofrules / ((n - RulesRegistery.starttime) / 1000)) + " : Total time "
+ ((n - RulesRegistery.starttime) / (1000 * 60)) + " : " + new Date());
}
if (!RuleRunTimeRegistery.isFireuntilHalt) {
if (RulesRegistery.numberofrules % RulesRegistery.printEPS == 0) {
System.out.println("Running Rules " + RulesRegistery.numberofrules + " EPS : "
+ (RulesRegistery.numberofrules / ((n - RulesRegistery.starttime) / 1000))
+ " : Total time " + ((n - RulesRegistery.starttime) / (1000 * 60)) + " : "
+ new Date());
}
ksession.fireAllRules();
if (RulesRegistery.numberofrules % RulesRegistery.printEPS == 0) {
System.out.println("Runned Rules " + RulesRegistery.numberofrules + " EPS : "
+ (RulesRegistery.numberofrules / ((n - RulesRegistery.starttime) / 1000))
+ " : Total time " + ((n - RulesRegistery.starttime) / (1000 * 60)) + " : "
+ new Date());
}
}
RulesRegistery.numberofrules++;
RuleRunTimeRegistery.lasttiem = n;
} catch (Exception ee) {
ee.printStackTrace();
}
}
}
Unless I've missed it: there isn't a retract statement in your code. This means that you keep inserting objects, with the usual result, after some time.
Retract facts as soon they aren't needed any more in any of your rules.

Java FX minigolf game - how to slow down the moving ball

I am beginner and trying to create a simple minigolf game with Java FX.
I built small golfcourse using lines. I get user input about hit strength from the slider and can make a hit using keyboard into 8 different directions.
If I hit for example button H, ball starts to move to right. If slider value was minimum, it moves slowly and if its maximum, it moves very fast.
But I cannot make the movement slow down until it stops.
Any ideas how to do that? My code so far is below.
Thank You in advance!
package sample;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class Main extends Application {
double directionx = 0;
double directiony = 0;
Line line1,line2,line3,line4,line5,line6,line7,line8,line9;
#Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Minigolf");
Pane pane = new Pane();
Scene scene = new Scene(pane, 900, 600);
pane.setStyle("-fx-background-color: green");
primaryStage.setScene(scene);
Slider slider = new Slider();
slider.setMin(1);
slider.setMax(10);
slider.setValue(1);
slider.setShowTickLabels(true);
slider.setShowTickMarks(true);
slider.setLayoutX(10);
slider.setLayoutY(10);
Circle ball = new Circle(10);
Circle hole = new Circle(15);
hole.setCenterX(75);
hole.setCenterY(430);
hole.setFill(Color.YELLOW);
ball.setCenterX(100);
ball.setCenterY(300);
// creating golfcourse with lines
line1 = new Line(50,200,500,200);
line2 = new Line(50,350,650,350);
line3 = new Line(50,200,50,350);
line4 = new Line(500,200,500,50);
line5 = new Line(650,350,650,200);
line6 = new Line(500,50,800,50);
line7 = new Line(800,50,800,500);
line8 = new Line(800,500,50,500);
line9 = new Line(50,500,50,350);
pane.getChildren().addAll(slider,ball,hole,line1,line2,line3,line4,line5,line6,line7,line8,line9);
new AnimationTimer() {
#Override
public void handle(long now) {
double ballY = ball.getCenterY();
double newballY = ballY + directiony;
// if ball touches vertical walls
if (ball.getBoundsInParent().intersects(line5.getBoundsInParent())
|| ball.getBoundsInParent().intersects(line3.getBoundsInParent())
|| ball.getBoundsInParent().intersects(line4.getBoundsInParent())
|| ball.getBoundsInParent().intersects(line7.getBoundsInParent())
|| ball.getBoundsInParent().intersects(line9.getBoundsInParent())) {
// changes direction
directionx = directionx * -1;
}
ball.setCenterX(ball.getCenterX() + directionx);
ball.setCenterY(newballY);
// if ball touches horizontal walls
if (ball.getBoundsInParent().intersects(line1.getBoundsInParent())
|| ball.getBoundsInParent().intersects(line2.getBoundsInParent())
|| ball.getBoundsInParent().intersects(line6.getBoundsInParent())
|| ball.getBoundsInParent().intersects(line8.getBoundsInParent())) {
directiony = directiony * -1;
}
// if ball touches hole, then game is over
if (ball.getBoundsInParent().intersects(hole.getBoundsInParent())) {
System.out.println("Game over");
pane.getChildren().removeAll(ball);
}
}
}.start();
// I get the slider value and making array where are 10 different strengts
scene.setOnKeyPressed(event -> {
double b = Math.round(slider.getValue());
b--;
int c = (int) b;
double [] strengts = new double[10];
double k = 0.1;
for (int i = 0; i < strengts.length; i++) {
strengts[i] = k;
k = k + 0.5;
}
// 8 different directions to move the ball
if (event.getCode().equals(KeyCode.H)) {
directionx = directionx + strengts[c];
}
else if(event.getCode().equals(KeyCode.F)) {
directionx = directionx - strengts[c];
}
else if(event.getCode().equals(KeyCode.V)) {
directiony=directiony + strengts[c];
}
else if(event.getCode().equals(KeyCode.T)) {
directiony= directiony - strengts[c];
}
else if(event.getCode().equals(KeyCode.B))
{
directionx = directionx + strengts[c];
directiony = directiony + strengts[c];
}
else if(event.getCode().equals(KeyCode.Y))
{
directionx = directionx + strengts[c];
directiony = directiony - strengts[c];
}
else if(event.getCode().equals(KeyCode.R))
{
directionx = directionx - strengts[c];
directiony = directiony - strengts[c];
}
else if(event.getCode().equals(KeyCode.C))
{
directionx = directionx - strengts[c];
directiony = directiony + strengts[c];
}
});
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Just use physics for friction. Assume for every frame the speed (v) remains constant.
Energy of a ball (mass m):
E = 0.5 * m * v²
Work for friction based on distance (s) traveled and a friction constant μ
ΔE = s * m * μ = Δt * v * m * μ
The new energy is E - ΔE which you can use with the first formula to calculate the new speed v':
0.5 * m * v'² = 0.5 * m * v² - s * m * μ
v'² = v² - s * μ * 2
v' = sqrt(v² - s * μ * 2)
The above assumes the ground is flat.
This allows you to decrease the speed like this:
#Override
public void start(Stage primaryStage) {
Point2D direction = new Point2D(1, 1).normalize();
Circle c = new Circle(10, 10, 10);
Timeline tl = new Timeline();
tl.getKeyFrames().setAll(new KeyFrame(Duration.seconds(1 / 60d), new EventHandler() {
double speed = 3;
double friction = 0.02;
#Override
public void handle(Event event) {
double distance = speed;
Point2D movement = direction.multiply(distance);
c.setCenterX(c.getCenterX() + movement.getX());
c.setCenterY(c.getCenterY() + movement.getY());
double energyBefore = speed * speed;
double energyLost = distance * friction;
if (energyLost > energyBefore) {
tl.stop();
speed = 0;
System.out.println("stopped");
} else {
speed = Math.sqrt(energyBefore - energyLost);
}
}
}));
tl.setCycleCount(Animation.INDEFINITE);
Pane root = new Pane();
root.getChildren().add(c);
Scene scene = new Scene(root, 400, 400);
scene.setOnMouseClicked(evt -> tl.play());
primaryStage.setScene(scene);
primaryStage.show();
}
Thank You for the reply, but as a beginner I found now by myself simpler solution.
I just add 4 if-statements as follows:
if (directionx>0) {
directionx = directionx - 0.01;
}
if(directionx<0){
directionx = directionx + 0.01;
}
if(directiony>0) {
directiony = directiony - 0.01;
}
if(directiony<0) {
directiony = directiony + 0.01;
}
Perhaps the in real physically its somehow wrong, but it looks quite real for me.

Binding Scene size properties to Stage JavaFX

I need to adjust the size of a Scene to the current size of the Stage/Window.
Currently when I resize the Stage/Window the Scene resizes as well, but not to the same size. The Scene contains a StackPane.
I looked for a way to bind but didn't find anything, setters for the size parameters of the Scene also aren't available it seems. Does anyone know a way to get this done?
EDIT: Here's the Code of my Class atm.
public class SimpleSun extends Application {
// Controls
Label lblPos = new Label();
Stage primaryStage;
List<Visibility> vislist;
Scene scene;
Rectangle rect;
Circle circle;
Line line1;
Line line2;
// Variables
private double sunDiameter = 700;
private Integer center = 400;
int fovrad = 80;
int fovpxl = calculatePixelsFromRad(fovrad);
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
#SuppressWarnings("static-access")
#Override
public void start(final Stage stage) {
// Initialize Containers
this.primaryStage = stage;
primaryStage.setTitle("0.1-alpha -- Sun Simulation");
BorderPane root = new BorderPane();
scene = new Scene(root, 800, 800);
StackPane sp = new StackPane();
// Paint Graphics
rect = new Rectangle(center - fovpxl / 2, center - fovpxl / 2, fovpxl,
fovpxl);
circle = new Circle(400, 400, 350);
line1 = new Line(0, 0, 0, scene.getHeight());
line2 = new Line(0, 0, scene.getHeight(), 0);
// Insert Controls
sp.getChildren().addAll(circle, line1, line2, lblPos, rect);
sp.setAlignment(lblPos, Pos.TOP_LEFT);
lblPos.setStyle("margin-top:10px");
root.setCenter(sp);
primaryStage.setScene(scene);
// Binding Circle size to stage & Scene size to Stage
circle.radiusProperty().bind(
primaryStage.widthProperty().divide(2).subtract(50));
circle.centerXProperty().bind(primaryStage.widthProperty().divide(2));
circle.centerYProperty().bind(primaryStage.widthProperty().divide(2));
// Assign Handlers
line1.setOnMouseClicked(mouseHandler);
line1.setOnMouseMoved(mouseHandler);
line2.setOnMouseClicked(mouseHandler);
line2.setOnMouseMoved(mouseHandler);
circle.setOnMouseClicked(mouseHandler);
circle.setOnMouseMoved(mouseHandler);
rect.setOnMouseClicked(mouseHandler);
rect.setOnMouseMoved(mouseHandler);
scene.widthProperty().addListener(cListener);
scene.heightProperty().addListener(cListener);
// Properties
circle.setFill(Color.YELLOW);
circle.setStroke(Color.BLACK);
rect.setFill(null);
rect.setStroke(Color.BLACK);
primaryStage.show();
}
EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() {
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getEventType() == MouseEvent.MOUSE_CLICKED) {
int x = (int) mouseEvent.getSceneX();
int y = (int) mouseEvent.getSceneY();
DoubleMatrix1D pCoords = calculateXYRad(x, y);
final ISource p = new GaussianRadialSource(pCoords.get(0),
pCoords.get(1), 1, 1, 0);
MainSimulation.runSim(p, fovrad);
// DEBUG
// String message = "Source Position: " + mouseEvent.getSceneX()
// + " / " + mouseEvent.getSceneY();
// System.out.println(message);
} else if (mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED) {
int x = (int) mouseEvent.getSceneX();
int y = (int) mouseEvent.getSceneY();
if (mouseEvent.getSource().getClass().equals(Circle.class)) {
((Circle) mouseEvent.getSource())
.setCursor(Cursor.CROSSHAIR);
} else if (mouseEvent.getSource().getClass().equals(Line.class)) {
((Line) mouseEvent.getSource()).setCursor(Cursor.CROSSHAIR);
} else if (mouseEvent.getSource().getClass()
.equals(Rectangle.class)) {
((Rectangle) mouseEvent.getSource())
.setCursor(Cursor.CROSSHAIR);
}
DoubleMatrix1D pCoords = calculateXYRad(x, y);
// Adjust label to new cursor position
lblPos.setText((pCoords.get(0) + " :: " + pCoords.get(1)));
// DEBUG
System.out.println("x: " + pCoords.get(0) + ", y: "
+ pCoords.get(1));
}
}
};
ChangeListener<? super Number> cListener = new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> scenewidth,
Number oldValue, Number newValue) {
// System.out.println(primaryStage.getHeight());
// Adjust Size of Window instead of binding
if (primaryStage.getHeight() < primaryStage.getWidth()) {
primaryStage.setWidth(primaryStage.getHeight());
center = (int) (primaryStage.getHeight() / 2);
sunDiameter = primaryStage.getHeight() - 100;
}
if (primaryStage.getWidth() < primaryStage.getHeight()) {
primaryStage.setHeight(primaryStage.getWidth());
center = (int) (primaryStage.getWidth() / 2);
sunDiameter = primaryStage.getWidth() - 100;
}
// Adjust Center and Sun Diameter to new Window Size
repaintSimpleSun();
System.out.println(primaryStage.getWidth() + " " + primaryStage.getHeight());
System.out.println(scene.getWidth() + " " + scene.getHeight());
System.out.println(center + " " + sunDiameter);
}
};
private DoubleMatrix1D calculateXYRad(int x, int y) {
double X = ((x - center) * (Units.SUN_HALF_DIAMETER_RAD * 2.0) / sunDiameter);
double Y = ((y - center) * (Units.SUN_HALF_DIAMETER_RAD * 2.0) / sunDiameter);
return DoubleFactory1D.dense.make(new double[] { X, Y });
}
private int calculatePixelsFromRad(int rad) {
int pixels = (int) ((sunDiameter) / (Units.SUN_HALF_DIAMETER_RAD * 2) * rad);
// System.out.println(pixels);
return pixels;
}
private void repaintSimpleSun() {
fovpxl = calculatePixelsFromRad(fovrad);
rect.setHeight(fovpxl);
rect.setWidth(fovpxl);
rect.setX(center - (fovpxl / 2));
rect.setY(center - (fovpxl / 2));
line1.setEndY(primaryStage.getWidth());
line2.setEndX(primaryStage.getHeight());
}
}

Blackberry APplication not rendering well on PORSCHE phones

I have got a Blackberry native application I have been working on in the past few weeks.
Basically it consists of a few screens in which I get to draw the designs of my screen by overriding the paint method of the FieldManagers
I have tested on blackberry 4.5 and other blackberry's.
It has rendered well so far until I ran into a hitch testing on Blackberry's Porsche version
which does not render my designs well. What I experience is that on scrolling, my screen gets wiped off.
Pls does any one here experienced such issues in the past and what would be the cause. I would be willing to show sections of the code to give insight into the issues I am experiencing. Least I mention it displays well on the simulator without these issues.
I have posted a sample screen which is my login screen:
final VerticalFieldManager everythingPanel = new VerticalFieldManager(VERTICAL_SCROLL)
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(new UtilNew().ashbrand);
graphics.clear();
super.paint(graphics);
}
public void sublayout(int width, int height){
super.sublayout(Display.getWidth(),Display.getHeight());
setExtent(Display.getWidth(), Display.getHeight());
}
};
final VerticalFieldManager spaceHolder1 = new VerticalFieldManager()
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(new Util().ashbrand);
graphics.clear();
super.paint(graphics);
}
public void sublayout(int width, int height){
super.sublayout(Display.getWidth(),topSpaceHeight);
setExtent(Display.getWidth(), topSpaceHeight);
}
};
final VerticalFieldManager contentHolderPix = new VerticalFieldManager(VerticalFieldManager.VERTICAL_SCROLL)
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(util.ashbrand);//black
graphics.setColor(new Util().whitebrand);
System.out.println(">>>>!!!!>>>>" + "img/icons/logo" + new Util().getResource() + ".png");
EncodedImage image_1 = EncodedImage.getEncodedImageResource("img/icons/icon" + new Util().getResource() + ".png");
setFont(util.initializeUtilFont("Arial", editFieldFontHeaderSize, Font.BOLD));
int startHere = topSpaceHeight - image_1.getHeight() - 5;
int imageWidth1 = (int)((Display.getWidth() - image_1.getWidth() - getFont().getAdvance("Sign In"))/2);
graphics.drawBitmap(new XYRect(imageWidth1 - 10 - whiteBgEdge.left - whiteBgEdge.right, startHere, image_1.getWidth(), image_1.getHeight()), image_1.getBitmap(), 0, 0);
int startfonty = startHere + ((image_1.getHeight() - getFont().getHeight())/2);
graphics.drawText("Sign In", imageWidth1, startfonty);
super.paint(graphics);
}
public void sublayout(int width, int height){
super.sublayout(whiteBgWidth,topSpaceHeight);
setExtent(whiteBgWidth, topSpaceHeight);
setMargin(whiteBgEdge);
}
};
System.out.println("whiteBgWidth>>>>" + whiteBgWidth);
System.out.println("padExtWhiteBg>>>>" + padExtWhiteBg);
usernameField = utilNew.newEditTextField(editFieldWidth, editFont.getHeight(), 30,
EditField.NO_NEWLINE, "", editFieldPad, editFont, false, "Username");
passwordField = utilNew.newPasswordField(editFieldWidth, editFont.getHeight(), 30,
PasswordEditField.NO_NEWLINE, "Password", editFieldPad, editFont);
//usernameField.setMargin(holderPad1);
if(user_!=null && user_.getSignInUserName()!=null && user_.getSignInUserName().trim().length()>0)
usernameField.setText(user_.getSignInUserName());
final int edHt = editFont.getHeight() + editFieldPad.top + editFieldPad.bottom;
final int edWt = editFieldWidth + editFieldPad.left + editFieldPad.right;
System.out.println("edHt = " + edHt);
System.out.println("edWt = " + edWt);
System.out.println("HolderPad1 = " + holderPad1.top + ", " + holderPad1.bottom + ", " + holderPad1.left + ", " + holderPad1.right);
usernameFieldHolder = utilNew.generateEditTextField(usernameField, true, holderPad1, edHt, edWt, true);
passwordFieldHolder = utilNew.generateEditTextField(passwordField, true, holderPad2, edHt, edWt, false);
final int height_ = edHt + edHt + holderPad1.top + holderPad1.bottom + holderPad2.top + holderPad2.bottom + 20;
System.out.println("height___>>>>>" + height_);
final VerticalFieldManager contentHolder1 = new VerticalFieldManager()
{
public void paint(Graphics graphics)
{
//System.out.println(edHt + "," + edHt + "," + holderPad1.top + "," + holderPad1.bottom + "," + holderPad2.top + "," + holderPad2.bottom);
graphics.setBackgroundColor(util.ashbrand);//black
graphics.setColor(new Util().whitebrand);
graphics.drawRoundRect(0, 0, whiteBgWidth, height_, 20, 20);
graphics.fillRoundRect(0, 0, whiteBgWidth, height_, 20, 20);
graphics.setColor(0x00808080);
//System.out.println("This is changed?");
//System.out.println("<<<<<<.." + usernameFieldHolder.getPreferredHeight() + "hfm.getPreferredHeight() = 0" + usernameFieldHolder.getWidth() );
//graphics.drawLine(40, usernameField.getPreferredHeight(), whiteBgWidth, usernameField.getPreferredHeight());/**/
super.paint(graphics);
}
public void sublayout(int width, int height){
System.out.println(Display.getHeight() + " - " + Display.getWidth());
System.out.println("Wdith & height = " + width + " && " + height);
System.out.println("Wdith & this.getPreferredHeight() = " + this.getWidth() + " && " + this.getHeight());
super.sublayout(whiteBgWidth,height_);
setExtent(whiteBgWidth, height_);
setMargin(whiteBgEdge);
}
};
int buttonHeight = 70;
/*CustomManager hfm_buttons = util.generateHFM1(
contentHolder1.getPreferredWidth(),
buttonHeight,
new Util().whitebrand,
0);*/
//submitButton = new UtilNew().generateButtonField(0x333333, util.whitebrand, "LOGIN", null);
//registerButton = new UtilNew().generateButtonField(0x333333, util.whitebrand, "REGISTER", null);
final LabelField loginButton = new LabelField("", Field.FOCUSABLE)
{
private int hColor;
public boolean isFocusable() {
return true;
}
protected void drawFocus(Graphics g, boolean on){
XYRect rect = new XYRect();
getFocusRect(rect);
drawHighlightRegion(g, HIGHLIGHT_FOCUS, false, rect.x, rect.y, rect.width, rect.height);
}
public void paint(Graphics g)
{
EncodedImage left;
EncodedImage right;
EncodedImage center;
if(isFocus())
{
left = EncodedImage.getEncodedImageResource("img/buttons/left.png");
center = EncodedImage.getEncodedImageResource("img/buttons/center.png");
right = EncodedImage.getEncodedImageResource("img/buttons/right.png");
g.setColor(util.green);
hColor = 0xcccccc;
}
else
{
left = EncodedImage.getEncodedImageResource("img/buttons/_left.png");
center = EncodedImage.getEncodedImageResource("img/buttons/_center.png");
right = EncodedImage.getEncodedImageResource("img/buttons/_right.png");
g.setColor(util.greenDark);
hColor = util.ashbrand;
}
//g.fillRect(0, 0, getPreferredWidth(), getPreferredHeight());
int totalWidth = whiteBgWidth + 4;
XYRect left_edge=new XYRect(2, 2, left.getWidth(), left.getHeight());
g.drawBitmap(left_edge, left.getBitmap(), 0, 0);
//invalidate();
int startX= (Display.getWidth() - totalWidth)/2;
int vount = (int)((totalWidth - left.getWidth() - right.getWidth())/center.getWidth()) - 3;
//System.out.println("vount = " + vount);
int widthbt = 0;
for(int c=0; c<vount; c++)
{
widthbt = left.getWidth() + (c*center.getWidth())+2;
XYRect center_edge=new XYRect(widthbt, 2, center.getWidth(), center.getHeight());
g.drawBitmap(center_edge, center.getBitmap(), 0, 0);
}
XYRect right_edge=new XYRect(widthbt,2, right.getWidth(), right.getHeight());
g.drawBitmap(right_edge, right.getBitmap(), 0, 0);
//invalidate();
//g.drawBitmap(right_edge, right.getBitmap(), 0, 0);
//g.fillRect(left_edge.getWidth(), 0, getPreferredWidth(), getPreferredHeight());
int colorOld = g.getColor();
g.setColor(hColor);
g.drawRoundRect(0, 0, totalWidth-4, left.getHeight()+4, 3, 3);
g.setColor(colorOld);
if(isFocus())
{
g.setColor(util.black);
}
else
{
g.setColor(util.whitebrand);
}
int height = (left.getHeight() - getFont().getHeight())/2;
int width = (totalWidth - getFont().getAdvance("Sign In"))/2;
g.drawText("Sign In", width, height);
setExtent(totalWidth+ 5,left.getHeight() + 10);
//setMargin(new XYEdges(20, 10, 0, whiteBgEdge.left));
invalidate();
super.paint(g);
}
public int getPreferredHeight() {
return getFont().getHeight() + 20;
}
public int getPreferredWidth() {
return (int)(whiteBgWidth);
}
protected boolean navigationClick(int status, int time) {
removeAllMenuItems();
String userName = usernameField.getText().toString().toLowerCase();
user_.setSignInUserName(userName);
String passWord = passwordField.getText().toString();
System.out.println("username = " + userName + " & password = " + passWord);
User user = User.getInstance();
System.out.println(">>instance of user from sign in: " + user);
Records record = new Records();
if(passWord.trim().length() < 2 || userName.trim().length() < 2){
Dialog.alert("Invalid username and/or password entered");
SignIn screen = new SignIn();
ScreenController screenController = ScreenController.getInstance();
screenController.addNewScreen(screen);
}else{
System.out.println("else if data is calid");
String hashPassword = user.md5Java(passWord);
hashPassword = "e86e107b113b0f830b9b817b4a9addb8";
user_.setUserName(userName);
user_.setPassword(passWord);
System.out.println("Check data availability");
try
{
FileConnection fc = (FileConnection)Connector.open(utilNew.FOLDER_LOCATION);
FileConnection fc1 = (FileConnection)Connector.open(utilNew.FOLDER_LOCATION_REF);
if (!fc.exists())
{
fc.mkdir();
if (!fc1.exists())
{
fc.mkdir();
}
}
fc.close();
}
catch (IOException ioe)
{
System.out.println(ioe.getMessage() );
}
if((record.isDataAvailable(record.userTable)==true))
{
System.out.println(">>>>### -1 ");
String[] allRecords = record.getAllRecords(record.userTable);
boolean proceedYes = true;
int count = 0;
while(proceedYes && count<allRecords.length)
{
System.out.println(">>>> Record = " + allRecords[count]);
//Dialog.alert(">>>> Record = " + allRecords[count]);
DataInputStream is = new DataInputStream(new ByteArrayInputStream(allRecords[count].getBytes()));
try {
System.out.println(">>>>555");
//System.out.println(">>>>" + is.readUTF() + " && " + is.readUTF() + " && " + is.readUTF());
String l = is.readUTF();
String u = is.readUTF();
String p = is.readUTF();
//System.out.println("e>>>>" + is.readUTF() + " && " + is.readUTF() + " && " + is.readUTF());
System.out.println("f>>>>" + l + " && " + u + " && " + p);
System.out.println("g>>>>" + userName + " && " + passWord + " && " + p);
if(u.equals(userName) && p.equals(passWord))
{
//Dialog.alert(">>>>12");
System.out.println(">>>889948444>");
proceedYes = false;
MenuLists screen = new MenuLists(10);
//UiApplication.getUiApplication().pushScreen(homeScreen);
ScreenController screenController = ScreenController.getInstance();
screenController.setCurrentScreen(SignIn.this);
screenController.addNewScreen(screen);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(">>>>Error " + e.getMessage() + " && " + e.toString() );
}
count++;
}
if(proceedYes)
{
System.out.println(">>>>### 3 ");
Hashtable jj = new Hashtable();
boolean proceedNow = false;
jj.put("username", userName);
jj.put("password", passWord);
jj.put("url", "https://localhost:8080/signinws/rest/account/login2");
System.out.println("object sent to server: "+jj);
ProcessAction processAction = new ProcessAction(jj, 0, record);
PopUpScreen.showScreenAndWait(processAction, "Setting up our account. Please Wait");
}
}
else
{
System.out.println(">>>>### o ");
Hashtable jj = new Hashtable();
boolean proceedNow=false;
System.out.println(">>>>### 4 ");
jj.put("username", userName);
jj.put("password", passWord);
jj.put("url", "https://localhost:8080/signinws/rest/account/login2");
System.out.println("object sent to server: "+jj);
proceedNow = true;
ProcessAction processAction = new ProcessAction(jj, 0, record);
PopUpScreen.showScreenAndWait(processAction, "Please Wait");
}
}
return super.navigationClick(status, time);
}
};
final LabelField registerButton = new LabelField("", Field.FOCUSABLE)
{
public boolean isFocusable() {
return true;
}
protected void drawFocus(Graphics g, boolean on){
XYRect rect = new XYRect();
getFocusRect(rect);
drawHighlightRegion(g, HIGHLIGHT_FOCUS, false, rect.x, rect.y, rect.width, rect.height);
}
public void paint(Graphics g)
{
EncodedImage left;
EncodedImage right;
EncodedImage center;
int hColor;
if(isFocus())
{
left = EncodedImage.getEncodedImageResource("img/buttons/left.png");
center = EncodedImage.getEncodedImageResource("img/buttons/center.png");
right = EncodedImage.getEncodedImageResource("img/buttons/right.png");
g.setColor(util.green);
hColor = 0xcccccc;
}
else
{
left = EncodedImage.getEncodedImageResource("img/buttons/_left.png");
center = EncodedImage.getEncodedImageResource("img/buttons/_center.png");
right = EncodedImage.getEncodedImageResource("img/buttons/_right.png");
g.setColor(util.greenDark);
hColor = util.ashbrand;
}
//g.fillRect(0, 0, getPreferredWidth(), getPreferredHeight());
int totalWidth = whiteBgWidth + 4;
XYRect left_edge=new XYRect(2, 2, left.getWidth(), left.getHeight());
g.drawBitmap(left_edge, left.getBitmap(), 0, 0);
//invalidate();
int startX= (Display.getWidth() - totalWidth)/2;
int vount = (int)((totalWidth - left.getWidth() - right.getWidth())/center.getWidth()) - 3;
XYRect left_edgeH=new XYRect(0, 0, vount, left.getHeight()+2);
//System.out.println("vount = " + vount);
int widthbt = 0;
for(int c=0; c<vount; c++)
{
widthbt = left.getWidth() + (c*center.getWidth()) + 2;
XYRect center_edge=new XYRect(widthbt, 2, center.getWidth(), center.getHeight());
g.drawBitmap(center_edge, center.getBitmap(), 0, 0);
}
XYRect right_edge=new XYRect(widthbt,2, right.getWidth(), right.getHeight());
g.drawBitmap(right_edge, right.getBitmap(), 0, 0);
//invalidate();
//g.drawBitmap(right_edge, right.getBitmap(), 0, 0);
//g.fillRect(left_edge.getWidth(), 0, getPreferredWidth(), getPreferredHeight());
int colorOld = g.getColor();
g.setColor(hColor);
g.drawRoundRect(0, 0, totalWidth-4, left.getHeight()+4, 3, 3);
g.setColor(colorOld);
if(isFocus())
{
g.setColor(util.black);
}
else
{
g.setColor(util.whitebrand);
}
int height = (left.getHeight() - getFont().getHeight())/2;
int width = (totalWidth - getFont().getAdvance("Create An Account"))/2;
g.drawText("Create An Account", width, height);
setExtent(totalWidth + 5,left.getHeight() + 10);
setPosition(0, getFont().getHeight() + 30);
invalidate();
super.paint(g);
}
public int getPreferredHeight() {
return getFont().getHeight() + 20;
}
public int getPreferredWidth() {
return (int)(whiteBgWidth);
}
protected boolean navigationClick(int status, int time) {
removeAllMenuItems();
RegisterScreen registerScreen = new RegisterScreen();
ScreenController screenController = ScreenController.getInstance();
screenController.addNewScreen(registerScreen);
return super.navigationClick(status, time);
}
};
final VerticalFieldManager spaceHolder2 = new VerticalFieldManager(NO_VERTICAL_SCROLL | NO_HORIZONTAL_SCROLL)
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(utilNew.ashbrand);
graphics.clear();
super.paint(graphics);
}
public void sublayout(int width, int height){
int w = whiteBgWidth;
super.sublayout(w, (loginButton.getPreferredHeight() * 2) + 40);
setExtent(w, (loginButton.getPreferredHeight() * 2) + 40);
int startX = (int)((Display.getWidth() - whiteBgWidth)/2);
setMargin(new XYEdges(20, 0, 0, startX));
}
};
spaceHolder2.add(loginButton);
spaceHolder2.add(registerButton);
//spaceHolder2.add(registerButton);
spaceHolder1.add(contentHolderPix);
everythingPanel.add(spaceHolder1);
contentHolder1.add(usernameFieldHolder);
contentHolder1.add(passwordFieldHolder);
/*passwordFieldDummyHolder.setFocusListener(new FocusChangeListener(){
public void focusChanged(Field field, int eventType) {
// TODO Auto-generated method stub
if(eventType == FocusChangeListener.FOCUS_GAINED)
{
contentHolder1.replace(passwordFieldDummyHolder, passwordFieldHolder);
}
}
});
passwordFieldHolder.setFocusListener(new FocusChangeListener(){
public void focusChanged(Field field, int eventType) {
// TODO Auto-generated method stub
if(eventType == FocusChangeListener.FOCUS_LOST)
{
System.out.println(">>>>>|>>>" + passwordFieldHolder.getIndex());
System.out.println(">>>>>|>>>" + passwordFieldDummyHolder.getIndex());
if(passwordField.getText().length()==0)
{
System.out.println(">>>>>1>>>");
passwordFieldDummyHolder = utilNew.generateEditTextField(passwordFieldDummy, true, holderPad2, edHt, edWt, false);
contentHolder1.replace(passwordFieldHolder, passwordFieldDummyHolder);
//loginButton.setFocus();
}
System.out.println(">>>>>2>>>");
System.out.println(">>>>>2>>>");
}
}
});*/
everythingPanel.add(contentHolder1);
everythingPanel.add(spaceHolder2);
add(everythingPanel);
}
I don't know what your problem actually is, but from what I have seen in your sample code it is clear that you are using the UI framework in a way that is not correct. You need to fix these issues before proceeding further.
Here is an example:
final VerticalFieldManager everythingPanel = new VerticalFieldManager(VERTICAL_SCROLL)
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(new UtilNew().ashbrand);
graphics.clear();
super.paint(graphics);
}
public void sublayout(int width, int height){
super.sublayout(Display.getWidth(),Display.getHeight());
setExtent(Display.getWidth(), Display.getHeight());
}
};
In this case you ask the parent Manager to lay itself out and give it specific sizes to do so. When doing this, you need to be sure that the sizes you are giving the parent class are not bigger than the size you have been given, So it is more correct to code something like:
super.sublayout(Math.min(Display.getWidth(), width),Math.min(Display.getHeight(), height));
What this will do is attempt to layout the Fields that are contained in the Manager, within the confines of the screen space you have told it to use (in this case the size of the screen). Having done this, it will set the actual size that it needs - in other words, at the end of the layout method, VerticalFieldManager will know how big it needs to be and will set that size. Then it returns. And then you do this:
setExtent(Display.getWidth(), Display.getHeight());
Effectively now you have a VerticalFieldManager that thinks it is working in a certain size, and will optimise its painting around that size, and you have potentially given it a different size. This could confuse!
The same comments apply within a Field's layout() method too.
In other words, if you are going to let the super class layout the Fields, then let the super class set the size, otherwise things can be confused.
Here is another, in fact worse, example:
final VerticalFieldManager spaceHolder2 = new VerticalFieldManager(NO_VERTICAL_SCROLL | NO_HORIZONTAL_SCROLL)
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(utilNew.ashbrand);
graphics.clear();
super.paint(graphics);
}
public void sublayout(int width, int height){
int w = whiteBgWidth;
super.sublayout(w, (loginButton.getPreferredHeight() * 2) + 40);
setExtent(w, (loginButton.getPreferredHeight() * 2) + 40);
int startX = (int)((Display.getWidth() - whiteBgWidth)/2);
setMargin(new XYEdges(20, 0, 0, startX));
}
};
Why is this worse? Because of this line:
setMargin(new XYEdges(20, 0, 0, startX));
Remember the point of sublayout is to position all your Fields on the screen. You have invoked the super.sublayout() processing to do this, and then, once it has done it, you suddenly say actually, I want some margins on the Field. Again you are potentially confusing the processing - in the middle of laying out the Fields you are changing one of the factors that is related to laying the Fields out...
I suggest you review the documentation around creating Managers (and presumably Fields) and look to remove any code that is disrupting this process. To assist you in this investigation, I recommend that you start here:
http://supportforums.blackberry.com/t5/Java-Development/MainScreen-explained/ta-p/606644
and then look at these:
http://supportforums.blackberry.com/t5/Java-Development/How-to-Extend-the-Screen/ta-p/446745
http://supportforums.blackberry.com/t5/Java-Development/How-to-Extend-the-Screen/ta-p/446745
http://supportforums.blackberry.com/t5/Java-Development/Create-a-custom-layout-manager-for-a-screen/ta-p/442990
http://supportforums.blackberry.com/t5/Java-Development/Create-custom-fields/ta-p/444962
You do a similar sort of thing in your paint routine. Here is a snippet:
public void paint(Graphics g)
{
EncodedImage left;
EncodedImage right;
...
left = EncodedImage.getEncodedImageResource("img/buttons/left.png");
...
setExtent(totalWidth + 5,left.getHeight() + 10);
setPosition(0, getFont().getHeight() + 30);
invalidate();
super.paint(g);
}
paint()'s job is to paint, not to position. Your code is supposed to position Fields in your layout (or sublayout) processing. But in the code above, you potentially move and change the size of a Field while it is trying to paint it!!!! This is bound to cause the system some problems.
The general rule in paint() is you do NOT change the Field, you just paint its current contents.
Two other things I will comment on with respect to the paint() code given above.
1) paint() is called often. You really want to minimise the processing done in paint. So don't create an image (see the left image in the code included above) each time you go through it. Create this once and then use paint to paint() the image. Doing excessive work in paint causes performance problems as well as killing the battery. This is the sort of thing you will not notice on the Simulator because it is so fast compared to the device.
2) And be aware that idea when using invalidate() is to repaint the Field. So there is no point calling invalidate() in the middle of paint(). In fact by doing this, you are causing an infinite loop. Each time you call paint(), your code is then using invalidate() to ask the Field to repaint itself, which causes paint() to be invoked, which asks for a invalidate(), ... You get the picture!.
I have pointed out problems in your layout processing and your paint processing. I'm not saying that these problems are in fact directly giving you the issues you see. It might be something else. You have supplied far too much code for me to review it all looking for that needle. If you want us to review code in detail, then I suggest you recreate the problem with a smaller sample of code. In fact I recommend you try to do this, because by cutting out code until the problem disappears, you will find out what actually is causing the problem.
Finally a couple of other points:
A) There is no real difference between doing background painting in paint() or paintBackground(). And in fact the only background painting you seem to do is this:
graphics.setBackgroundColor(new UtilNew().ashbrand);
graphics.clear();
which is absolutely fine in paint(), and I wouldn't bother changing this to use paintBackground() or a Background class. The one issue I have with this code is that fact that you create a new class instance of UtilNew each time paint is invoked (which is a lot). That won't help performance.
B) I would avoid calling Screen.invalidate() in a scroll change listener until you are sure that there is no other way to get the screen painted correctly. As noted, there is a lot of other suspect code in what you have supplied. Correct that before you try Screen.invalidate().

Resources