i am trying to make a navigation panel sliding out from left side. I have managed an animation already but i cannot solve one thing and that is green empty space left in left area of the program's window. Does anyone have an idea how to get rid of the green space on the left? Thanks
My code looks like this (just copy and paste, it should work)
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application
{
BorderPane slider;
BorderPane mainPane;
Rectangle clip;
Button show;
boolean displayed;
#Override
public void start(Stage primaryStage) throws Exception {
show = new Button("Press");
displayed = false;
mainPane = new BorderPane();
mainPane.setPrefSize(500,200);
slider = new BorderPane(); slider.setPrefHeight(200);
mainPane.setStyle("-fx-background-color: chartreuse");
slider.setStyle("-fx-background-color: aqua");
clip = new Rectangle(0,200);
slider.setPrefWidth(0);
slider.setClip(clip);
slider.setCenter(new Button("Hello"));
mainPane.setTop(show);
mainPane.setCenter(new TextArea("some text"));
mainPane.setLeft(slider);
show.setOnAction(event -> {
if (displayed)
{
Timeline tm = new Timeline();
KeyValue kv1 = new KeyValue(slider.translateXProperty(), -100);
KeyValue kv2 = new KeyValue(slider.prefWidthProperty(), 0);
KeyValue kv3 = new KeyValue(clip.widthProperty(), 0);
KeyFrame kf = new KeyFrame(Duration.millis(200), kv1, kv2, kv3);
tm.getKeyFrames().addAll(kf);
tm.play();
displayed = false;
}
else
{
Timeline tm = new Timeline();
KeyValue kv1 = new KeyValue(slider.translateXProperty(), 0);
KeyValue kv2 = new KeyValue(slider.prefWidthProperty(), 100);
KeyValue kv3 = new KeyValue(clip.widthProperty(), 100);
KeyFrame kf = new KeyFrame(Duration.millis(200), kv1, kv2, kv3);
tm.getKeyFrames().addAll(kf);
tm.play();
displayed = true;
}
});
Scene sc = new Scene(mainPane);
primaryStage.setScene(sc);
primaryStage.show();
}
}
You can add the slider (left child of the mainPane) when you are press on the button instead of adding it before hand. Then, when you press the button again, you can remove the slider after the transition is completed.
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application
{
BorderPane slider;
BorderPane mainPane;
Rectangle clip;
Button show;
boolean displayed;
#Override
public void start(Stage primaryStage) throws Exception {
show = new Button("Press");
displayed = false;
mainPane = new BorderPane();
mainPane.setPrefSize(500,200);
slider = new BorderPane();
slider.setPrefHeight(200);
mainPane.setStyle("-fx-background-color: chartreuse");
slider.setStyle("-fx-background-color: aqua");
clip = new Rectangle(0,200);
slider.setPrefWidth(0);
slider.setClip(clip);
slider.setCenter(new Button("Hello"));
mainPane.setTop(show);
mainPane.setCenter(new TextArea("some text"));
show.setOnAction(event -> {
if (displayed) {
Timeline tm = new Timeline();
KeyValue kv1 = new KeyValue(slider.translateXProperty(), -100);
KeyValue kv2 = new KeyValue(slider.prefWidthProperty(), 0);
KeyValue kv3 = new KeyValue(clip.widthProperty(), 0);
KeyFrame kf = new KeyFrame(Duration.millis(200), kv1, kv2, kv3);
tm.getKeyFrames().addAll(kf);
tm.play();
displayed = false;
tm.setOnFinished(e -> mainPane.setLeft(null));
} else {
mainPane.setLeft(slider);
Timeline tm = new Timeline();
KeyValue kv1 = new KeyValue(slider.translateXProperty(), 0);
KeyValue kv2 = new KeyValue(slider.prefWidthProperty(), 100);
KeyValue kv3 = new KeyValue(clip.widthProperty(), 100);
KeyFrame kf = new KeyFrame(Duration.millis(200), kv1, kv2, kv3);
tm.getKeyFrames().addAll(kf);
tm.play();
displayed = true;
}
});
Scene sc = new Scene(mainPane);
primaryStage.setScene(sc);
primaryStage.show();
}
}
You can also re-use the timline instead of creating a new one every time :)
I know this is an old thread, but there is a great JavaFX library available that would help here: controlsFX. In particular the HiddenSidesPane Control object.
Related
Update: I am using JavaFX 13
This problem happens across all my JavaFX programs, but this is one example. A user is supposed to be able to select options for a custom milkshake then get a receipt when they checkout. All of the object referencing and MVC works as it is supposed to, but when displaying the information using Text objects (javafx.scene.text.Text), they are overlapped by other objects around them. In the second and third images, I have the occurrences circled.
First launch of the program. The first image
Here is the code for the text pane in the second image:
After adding a few selections. The second Image
import Controllers.Controller;
import Entities.Milkshake;
import Interfaces.Observer;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import java.util.ArrayList;;
public class TextSummaryView extends AnchorPane implements Observer<Milkshake> {
private Milkshake model;
private Controller controller;
private VBox iceCreamOptions;
private VBox toppingOptions;
private Text totalCost;
private final double minHeight = 100.0;
private final double minWidth = 50.0;
public TextSummaryView() {
super();
iceCreamOptions = new VBox();
toppingOptions = new VBox();
totalCost = new Text("$0.00");
Button checkout = new Button("Checkout");
checkout.setOnAction(e -> controller.checkout());
Text iceCreamText = new Text("Click '-' to remove\nCurrent Ice Cream Selections:");
Text toppingText = new Text("Current Topping Selections");
iceCreamOptions.getChildren().add(iceCreamText);
toppingOptions.getChildren().add(toppingText);
this.getChildren().addAll(checkout, iceCreamOptions, toppingOptions, totalCost);
// Setting position of elements
setBottomAnchor(checkout, this.getHeight()-5.0);
setRightAnchor(checkout, this.getWidth()-5.0);
setLeftAnchor(totalCost, 5.0);
setBottomAnchor(totalCost, this.getHeight()-5.0);
setTopAnchor(iceCreamOptions, 5.0);
setLeftAnchor(iceCreamOptions, 5.0);
setTopAnchor(toppingOptions, Math.max(40.0, iceCreamOptions.getHeight() + 10.0));
setLeftAnchor(toppingOptions, 5.0);
this.setMinHeight(minHeight);
this.setMinWidth(minWidth);
}
/**
* Sets what the observer will watch
* #param obs An object that extends the Observable interface
*/
public void setTarget(Milkshake obs){
this.model = obs;
}
/**
* Removes the object from target
*/
public void removeTarget(){
this.model = null;
}
/**
* Called by observables to update the observer's data
*/
public void update(){
this.iceCreamOptions.getChildren().remove(1, this.iceCreamOptions.getChildren().size());
this.toppingOptions.getChildren().remove(1, this.toppingOptions.getChildren().size());
// Get Data
ArrayList<String> iceCreams = model.getIceCreams();
ArrayList<String> toppings = model.getToppings();
// Update the ice cream selections
int iceCreamIndex = 0;
for (String ic: iceCreams) {
AnchorPane selection = new AnchorPane();
Button removeButton = new Button("-");
Text iceCream = new Text(ic + ":");
Text cost = new Text("$1.00");
final int iceIndexFin = iceCreamIndex;
removeButton.setOnAction(e -> controller.removeIceCream(iceIndexFin));
selection.getChildren().addAll(removeButton, iceCream, cost);
setLeftAnchor(removeButton, 5.0);
setLeftAnchor(iceCream, 50.0);
setTopAnchor(iceCream, selection.getHeight()/3);
setLeftAnchor(cost, selection.getWidth()-5.0);
setTopAnchor(cost, selection.getHeight()/3);
this.iceCreamOptions.getChildren().add(selection);
iceCreamIndex ++;
}
// Update the topping selections
int toppingIndex = 0;
for (String top: toppings) {
AnchorPane selection = new AnchorPane();
Button removeButton = new Button("-");
Text topping = new Text(top + ":");
Text cost = new Text("$0.50");
final int topIndexFin = toppingIndex;
removeButton.setOnAction(e -> controller.removeTopping(topIndexFin));
selection.getChildren().addAll(removeButton, topping, cost);
setLeftAnchor(removeButton, 5.0);
setLeftAnchor(topping, 50.0);
setTopAnchor(topping, selection.getHeight()/3);
setLeftAnchor(cost, selection.getWidth()-5.0);
setTopAnchor(cost, selection.getHeight()/3);
this.toppingOptions.getChildren().add(selection);
toppingIndex ++;
}
setTopAnchor(iceCreamOptions, 5.0);
setLeftAnchor(iceCreamOptions, 5.0);
setTopAnchor(toppingOptions, Math.max(40.0, iceCreamOptions.getHeight() + 10.0));
setLeftAnchor(toppingOptions, 5.0);
this.totalCost.setText( "$" + this.model.getCost() + "0");
}
public void setController(Controller controller){
this.controller = controller;
}
}
Here is the code for the checkout screen. Pressing the checkout button. All are different text objects in a VBox. The third image
import Entities.Milkshake;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.util.ArrayList;
public class CheckoutView extends Stage {
VBox root = new VBox();
public CheckoutView(Milkshake ms) {
super();
// Get Data
ArrayList<String> iceCreams = ms.getIceCreams();
ArrayList<String> toppings = ms.getToppings();
// Update the ice cream selections
int iceCreamIndex = 0;
for (String ic: iceCreams) {
AnchorPane selection = new AnchorPane();
Text iceCream = new Text(ic + ":");
Text cost = new Text("$1.00");
final int iceIndexFin = iceCreamIndex;
selection.getChildren().addAll(iceCream, cost);
AnchorPane.setLeftAnchor(iceCream, 50.0);
AnchorPane.setLeftAnchor(cost, this.getWidth()-5.0);
this.root.getChildren().add(selection);
iceCreamIndex ++;
}
// Update the topping selections
int toppingIndex = 0;
for (String top: toppings) {
AnchorPane selection = new AnchorPane();
Text topping = new Text(top + ":");
Text cost = new Text("$0.50");
selection.getChildren().addAll(topping, cost);
AnchorPane.setLeftAnchor(topping, 50.0);
AnchorPane.setLeftAnchor(cost, this.getWidth()-5.0);
this.root.getChildren().add(selection);
toppingIndex ++;
}
AnchorPane total = new AnchorPane();
Text costTotal = new Text("$" +ms.getCost() + "0");
total.getChildren().add(costTotal);
AnchorPane.setLeftAnchor(total, this.getMaxWidth()-costTotal.getX());
BorderPane exitOptions = new BorderPane();
Button pay = new Button("Finish and Pay");
Button ret = new Button("Return to Order");
pay.setOnAction(e -> Platform.exit());
ret.setOnAction(e -> this.close());
exitOptions.setLeft(ret);
exitOptions.setRight(pay);
root.getChildren().add(exitOptions);
this.setTitle("Checkout");
this.setScene(new Scene(root));
}
public static void checkout(Milkshake ms) {
CheckoutView check = new CheckoutView(ms);
check.show();
}
}
Thank you in advance for all your help! :)
Javafx:How can text-to speech is done on animated text; I have applied a typewriter effect on text to make animated text, and now i want that it will speak word by word as typed. P.S. for Text-to-Speech iam using the "FreeTTS is a speech synthesis engine"
here is code snippet of my project
public void AnimattedTextToSpeech()
{
// Text to Speech
Voice voice;
VoiceManager vm=VoiceManager.getInstance();
voice=vm.getVoice("kevin16");
voice.allocate();
// TypeWritter Effect to the text
String str="Welcome! This is the Lesson number one";
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() > str.length()) {
timeline.stop();
} else {
textArea.setText(str.substring(0, i.get()));
i.set(i.get() + 1);
textArea.requestFocus();
textArea.end();
}
});
voice.speak(str);
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
But it is speaking every character as it is typing. But i want it speak word by word.
This works but it seems like you need to run the speech on a different thread.
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
*
* #author blj0011
*/
public class FreeTTTS extends Application
{
#Override
public void start(Stage primaryStage)
{
TextArea textArea = new TextArea();
// Text to Speech
Voice voice;
VoiceManager vm = VoiceManager.getInstance();
voice = vm.getVoice("kevin16");
voice.allocate();
// TypeWritter Effect to the text
String str = "Welcome! This is the Lesson number one";
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
AtomicInteger startIndex = new AtomicInteger();
AtomicInteger endIndex = new AtomicInteger();
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() >= str.length()) {
timeline.stop();
startIndex.set(endIndex.get());
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
else {
textArea.appendText(Character.toString(str.charAt(i.get())));
if (str.charAt(i.get()) == ' ') {
if (endIndex.get() == 0) {
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
else {
startIndex.set(endIndex.get());
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
}
i.set(i.get() + 1);
}
});
//voice.speak(str);
StackPane root = new StackPane(textArea);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
//voice.speak("Hello World");
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
I imagine you should divide text into strings, and start TTS the moment you start TypeWritter effect for each string.
Like this:
String str1 = "Welcome! This is the Lesson number one";
String[] temp = str1.split(" ");
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
for (String str : temp) {
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() > str.length()) {
timeline.stop();
} else {
textArea.setText(str.substring(0, i.get()));
i.set(i.get() + 1);
textArea.requestFocus();
textArea.end();
}
});
voice.speak(str);
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
My problem is, that after every keyframe the x- and y-Position of the rectangle should change by random.
Right now only when I start the program, the rectangles position is set by random, but not in the animation itself.
How can I do this, thanks a lot...
public class TimeLines extends Application {
private Rectangle rectBasicTimeline;
private Timeline timeline;
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Do Animation");
int x = new Random().nextInt(500);
int y = new Random().nextInt(400);
rectBasicTimeline = new Rectangle(x, y, 100, 50);
rectBasicTimeline.setFill(Color.RED);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
final Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.setAutoReverse(true);
final KeyValue kx = new KeyValue(rectBasicTimeline.xProperty(), x + 200);
final KeyValue ky = new KeyValue(rectBasicTimeline.yProperty(), y + 200);
final KeyValue kScale = new KeyValue(rectBasicTimeline.scaleXProperty(), 2);
final KeyValue kFade = new KeyValue(rectBasicTimeline.opacityProperty(), 0);
final KeyFrame kf = new KeyFrame(Duration.millis(3000), kx, ky, kScale, kFade);
timeline.getKeyFrames().add(kf);
timeline.play();
}
});
AnchorPane root = new AnchorPane();
root.getChildren().addAll(btn, rectBasicTimeline);
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I agree with #Roland, no need to create multiple Timeline. Reclicking the button just restarts the timeline with new KeyFrame:
public class StarFall extends Application
{
private Polygon star;
private Timeline timeline;
private final double shs = 5.0; // Star Hand Size
private final Random random = new Random();
#Override
public void start( Stage primaryStage )
{
// init shape
Pos initPos = getRandomPos();
star = new Polygon();
star.setLayoutX( initPos.x );
star.setLayoutY( initPos.y );
star.setFill( Color.YELLOW );
// the shape
star.getPoints().addAll( new Double[]
{
0.0, shs * 3,
shs * 2, shs * 2,
shs * 3, 0.0,
shs * 4, shs * 2,
shs * 6, shs * 3,
shs * 4, shs * 4,
shs * 3, shs * 6,
shs * 2, shs * 4
} );
// init timeline
timeline = new Timeline();
timeline.setCycleCount( Timeline.INDEFINITE );
timeline.setAutoReverse( true );
// init button
Button btnStart = new Button( "Do Animation" );
btnStart.setOnAction( ( e ) -> playNextKeyFrame() );
Button btnStop = new Button( "Stop Animation" );
btnStop.setLayoutX( 200 );
btnStart.setLayoutX( 0 );
btnStop.setOnAction( ( e ) -> timeline.stop() );
// init scene with root
AnchorPane root = new AnchorPane( btnStart, btnStop, star );
Scene scene = new Scene( root, 800, 600 );
// show
primaryStage.setScene( scene );
primaryStage.show();
}
private void playNextKeyFrame()
{
// generate next random start and end positions for star
Pos startPos = getRandomPos();
Pos endPos = getRandomPos();
// initial values (resetting)
star.setLayoutX( startPos.x );
star.setLayoutY( startPos.y );
star.setScaleX( 1 );
star.setScaleY( 1 );
star.setOpacity( 1 );
// target values
KeyValue kx = new KeyValue( star.layoutXProperty(), endPos.x );
KeyValue ky = new KeyValue( star.layoutYProperty(), endPos.y );
KeyValue kScaleX = new KeyValue( star.scaleXProperty(), 3 );
KeyValue kScaleY = new KeyValue( star.scaleYProperty(), 3 );
KeyValue kFade = new KeyValue( star.opacityProperty(), 0.0 );
// delay animation before start. Use this instead of THread.sleep() !!
timeline.setDelay( Duration.millis( random.nextInt( 2000 ) + 100 ) );
// restart timeline with new values
timeline.stop();
timeline.getKeyFrames().clear();
timeline.getKeyFrames().add( new KeyFrame( Duration.millis( 3000 ),
( e ) -> playNextKeyFrame(), kx, ky, kFade, kScaleX, kScaleY ) );
timeline.play();
}
private Pos getRandomPos()
{
int x = random.nextInt( 500 );
int y = random.nextInt( 400 );
Pos p = new Pos();
p.x = x + 200;
p.y = y + 200;
return p;
}
private class Pos
{
int x;
int y;
}
public static void main( String[] args )
{
launch( args );
}
}
You initialize the random numbers and hence the location once and use it all the time. What you need to do is to perform the animation cycle once and then create a new animation when the current one finishes.
Example:
import java.util.Random;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TimeLines extends Application {
private Rectangle rectBasicTimeline;
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Do Animation");
int x = new Random().nextInt(500);
int y = new Random().nextInt(400);
rectBasicTimeline = new Rectangle(x, y, 100, 50);
rectBasicTimeline.setFill(Color.RED);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
play();
}
});
AnchorPane root = new AnchorPane();
root.getChildren().addAll(btn, rectBasicTimeline);
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private void play() {
double x = new Random().nextInt(500);
double y = new Random().nextInt(400);
final Timeline timeline = new Timeline();
// cycle count = 2 because of autoreverse
timeline.setCycleCount(2);
timeline.setAutoReverse(true);
final KeyValue kx = new KeyValue(rectBasicTimeline.xProperty(), x + 200);
final KeyValue ky = new KeyValue(rectBasicTimeline.yProperty(), y + 200);
final KeyValue kScale = new KeyValue(rectBasicTimeline.scaleXProperty(), 2);
final KeyValue kFade = new KeyValue(rectBasicTimeline.opacityProperty(), 0);
final KeyFrame kf = new KeyFrame(Duration.millis(1000), kx, ky, kScale, kFade);
timeline.getKeyFrames().add(kf);
timeline.setOnFinished(e -> {
// create new animation after this animation finishes
play();
});
timeline.play();
}
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I wouldn't suggest this approach though, e. g. you run into problems with multiple timelines when you click the button multiple times. But I have no information what you're trying to do, so I'll leave it at that.
I'm working with Timelines and was hoping to hook up some KeyPress events to the stage that could alter the way the timeline changes the properties over the course it runs.
I know how to differentiate between what key was pressed and for what keys I want to listen, but need to know how I can determine if a key has just been pressed once, like typing, or if a key is being held down for a longer period of time, so that I can have the program make more rapid adjustments the longer the key is held down.
When a key is being held down, you keep on getting KEY_PRESSED events. You can count how many presses of the same key you get in a row:
SimpleIntegerProperty aCount = new SimpleIntegerProperty(0);
SimpleIntegerProperty bCount = new SimpleIntegerProperty(0);
KeyCombination a = new KeyCodeCombination(KeyCode.A);
KeyCombination b = new KeyCodeCombination(KeyCode.B);
scene.setOnKeyPressed(ke -> {
aCount.set(a.match(ke) ? aCount.get() + 1 : 0);
bCount.set(b.match(ke) ? bCount.get() + 1 : 0);
});
scene.setOnKeyReleased(ke -> {
if(a.match(ke)) { aCount.set(0); }
else if(b.match(ke)) { bCount.set(0); }
});
Here is a simple test application:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class KeySpeedTest extends Application {
#Override
public void start(Stage primaryStage) {
SimpleIntegerProperty aCount = new SimpleIntegerProperty(0);
SimpleIntegerProperty bCount = new SimpleIntegerProperty(0);
KeyCombination a = new KeyCodeCombination(KeyCode.A);
KeyCombination b = new KeyCodeCombination(KeyCode.B);
Label aLabel = new Label();
Label bLabel = new Label();
aLabel.textProperty().bind(Bindings.concat(" A: ", aCount));
bLabel.textProperty().bind(Bindings.concat(" B: ", bCount));
HBox root = new HBox(aLabel, bLabel);
Scene scene = new Scene(root, 300, 250);
scene.setOnKeyPressed(ke -> {
aCount.set(a.match(ke) ? aCount.get() + 1 : 0);
bCount.set(b.match(ke) ? bCount.get() + 1 : 0);
});
scene.setOnKeyReleased(ke -> {
if(a.match(ke)) { aCount.set(0); }
else if(b.match(ke)) { bCount.set(0); }
});
primaryStage.setScene(scene);
primaryStage.setTitle("Key Speed Test");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The code for the question is here - I am using Flash Builder 4.7, I will also post all the relevant code now:
Game.as (might be something wrong here)
package
{
import Classes.AvatarEnemy;
//import starling.animation.Juggler;
//import starling.core.Starling;
import starling.display.Sprite;
import flash.geom.Point;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.ui.Mouse;
import flash.ui.MouseCursorData;
public class Game extends Sprite
{
//private var juggler:Juggler = Starling.juggler;
[Embed(source="Classes/Avatarpic.png")]
private const Cursor:Class;
public var enemy:AvatarEnemy;
public function Game()
{
enemy = new AvatarEnemy();
addChild(enemy);
//var counter:int;
/*juggler.delayCall(function():void {
if(enemy.hitTest(cursor_D.hotSpot, true)) {
var score:int = counter;
trace(score);
};
counter++;
}, 1.0);*/
function createCustomCursor():void
{
var cursorBitmaps:Vector.<BitmapData> = new Vector.<BitmapData>();
cursorBitmaps.push((new Cursor() as Bitmap).bitmapData);
var mouseCursorData:MouseCursorData = new MouseCursorData();
mouseCursorData.data = cursorBitmaps;
mouseCursorData.frameRate = 30;
mouseCursorData.hotSpot = new Point(0, 0);
Mouse.registerCursor("customCursor", mouseCursorData);
Mouse.cursor = "customCursor";
}
createCustomCursor();
}
}
}
Startup.as (shouldn't be anything wrong here)
package
{
import flash.display.Sprite;
import starling.core.Starling;
import Game;
[SWF(width="400", height="300", frameRate="60", backgroundColor="#ffffff")]
public class Startup extends Sprite
{
private var _starling:Starling;
public function Startup()
{
_starling = new Starling(Game, stage);
_starling.start();
}
}
}
AvatarEnemy.as (might be something wrong here)
package Classes
{
import starling.display.Image;
import starling.display.Sprite;
import starling.textures.Texture;
public class AvatarEnemy extends Sprite
{
[Embed(source='Enemypic.png')]
private static var Enemypic:Class;
private var texture:Texture = Texture.fromBitmap(new Enemypic());
private var image:Image = new Image(texture);
public function AvatarEnemy()
{
image.x = 0;
image.y = 200;
addChild(image);
}
}
}
All of the code at the end of Game.as is me trying to make the cursor a certain image - I also need help with that too. But right now - the enemy object isn't being added to the stage for some reason, despite the fact that I use addChild(enemy). Anyone know why? Thanks.