Just wanted to see what you all thought about my program, I basically have two different classes that I designed to allow for automated wrapping of text in a circular pattern. This is my first bit of useful and reusable code. Let me know what can be improved or added.
Here are some screenshots I took of the program in action:
Below is the main part of the program to let you see how it is used within the program:
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.effect.BlendMode;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* Created by John on 7/17/2014.
*/
public class MouseEventDemo extends Application {
public double rotateImage;
Pane pane = new Pane();
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Set pane's properties
pane.setStyle("-fx-background-color: black");
// Create and add objects
setMouseTrail();
setCenterObject();
// Create a scene and place it in the stage
Scene scene = new Scene(pane, 600, 600);
primaryStage.setTitle("MouseTrailDemo"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
/** Set mouse trail */
public void setMouseTrail() {
// Create image for cursor
ImageView imageView = new ImageView(new Image("/image/anon5.jpg"));
imageView.setBlendMode(BlendMode.SCREEN);
imageView.setCache(true);
pane.getChildren().add(imageView);
// Create a new RotatingText object
Font font = Font.font("Courier New", FontWeight.BOLD, 12);
RotatingText circlePane = new RotatingText("We Are Anonymous",
220, font);
circlePane.setCircleSize(36);
circlePane.setTextColor(Color.LIME);
circlePane.relocate(imageView.getX(), imageView.getY());
pane.getChildren().add(circlePane);
// Rotation transform for animation counter clockwise
final Rotate rotationTransform = new Rotate(360, 0, 0);
circlePane.getTransforms().add(rotationTransform);
// Animate the RotatingText object
Timeline rotatingText = new Timeline(new KeyFrame(
Duration.seconds(5),
new KeyValue(rotationTransform.angleProperty(), 0)));
rotatingText.setCycleCount(Timeline.INDEFINITE);
rotatingText.play();
// Set text to circle image and image to follow mouse
pane.setOnMouseMoved(e -> {
imageView.setX(e.getX() - 10);
imageView.setY(e.getY() + 30);
circlePane.relocate(imageView.getX() + 34,
imageView.getY() + 29.5);
});
}
/** Set center object and animate it */
public void setCenterObject() {
// Create circular text
Font font2 = Font.font("Courier New", FontWeight.BOLD, 12);
CircularText circularText = new CircularText("We Are Anonymous",
325, 325);
circularText.setTextFill(Color.LIME);
circularText.setTextSize(12, 1.3, 1.1);
circularText.setFont(font2);
circularText.setTextRotate(90, 360);
circularText.setGapSpacing(0.95);
circularText.setTextStartDegree(360);
circularText.relocate(300, 300);
pane.getChildren().add(circularText);
// Rotation transform for circular text animation and image
final Rotate rotationTransform = new Rotate(360, 0, 0);
circularText.getTransforms().add(rotationTransform);
// Animate the RotatingText object
Timeline rotatingText = new Timeline(new KeyFrame(
Duration.seconds(10),
new KeyValue(rotationTransform.angleProperty(), 0)));
rotatingText.setCycleCount(Timeline.INDEFINITE);
rotatingText.play();
// Load image for center
ImageView imageView2 = new ImageView(new Image("/image/anon3.jpg"));
imageView2.setBlendMode(BlendMode.SCREEN);
imageView2.setCache(true);
imageView2.setX(circularText.getLayoutX() - 145);
imageView2.setY(circularText.getLayoutY() - 125);
pane.getChildren().add(imageView2);
// Create EventHandler for image
rotateImage = 0;
EventHandler<ActionEvent> eventHandler = e -> {
if (rotateImage == 360)
rotateImage = 0;
rotateImage += 1;
imageView2.setRotate(rotateImage);
};
// Animate the image rotation
Timeline timeline = new Timeline(new KeyFrame(
Duration.millis(35), eventHandler));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
}
Here is the RotatingText
class that controls the text rotating around the mouse trail:
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import java.util.ArrayList;
/**
* Created by John on 7/19/2014.
*/
public class RotatingText extends Pane {
private double circleSize;
private double textRotate;
private String phrase;
private double startDegree;
private double letterSpacing;
private double pointX;
private double pointY;
private double rotate;
// Objects and properties
ArrayList<String> phraseList;
private Text text;
private Font textFont;
private Color textColor;
/** Default Constructor */
public RotatingText() {
this.circleSize = 100;
this.textFont = new Font("Courier New", 15);
this.phrase = "Default";
this.startDegree = 220;
this.letterSpacing = 21;
this.textRotate = 100;
this.textColor = Color.BLACK;
paintText(this.phrase);
}
/** Constructor for setting phrase, starting degree, and the font */
public RotatingText(String phrase, double startDegree, Font font) {
this.circleSize = 100;
this.textFont = font;
this.textRotate = 90;
this.textColor = Color.BLACK;
this.phrase = phrase;
this.startDegree = startDegree;
this.letterSpacing = 21;
paintText(this.phrase);
}
/** Get the color of Font */
public Color getTextColor() {
return this.textColor;
}
/** Set the color of Font */
public void setTextColor(Color color) {
this.textColor = color;
paintText(this.phrase);
}
/** Get the Font */
public Font getTextFont() {
return this.textFont;
}
/** Set the Font */
public void setTextFont(Font font) {
this.textFont = font;
paintText(this.phrase);
}
/** Get the size of the circle */
public double getCircleSize() {
return this.circleSize;
}
/** Set the size of the circle */
public void setCircleSize(double circleSize) {
this.circleSize = circleSize;
paintText(this.phrase);
}
/** Get the rotation setting of the text */
public double getTextRotate() {
return this.textRotate;
}
/** Set the rotation setting of the text */
public void setTextRotate(double textRotate) {
this.textRotate = textRotate;
paintText(this.phrase);
}
/** Get the spacing between letters */
public double getLetterSpacing() {
return this.letterSpacing;
}
/** Set the spacing between letters */
public void setLetterSpacing(double letterSpacing) {
this.letterSpacing = letterSpacing;
paintText(this.phrase);
}
/** Paint's the text in a circular fashion */
private void paintText(String phrase) {
getChildren().clear();
// Create ArrayList and store each letter as a string
this.phraseList = new ArrayList<>(phrase.length());
for (int i = 0; i < phrase.length(); i++) {
phraseList.add(i, String.valueOf(phrase.charAt(i)));
}
// Create letters and place them around the circle
for (int i = 0; i < phrase.length(); i++) {
addLetter(this.textFont, this.textColor,
phraseList.get(i), startDegree);
getChildren().add(this.text);
startDegree += letterSpacing;
}
}
/** Create letter and add it to pane */
public void addLetter(Font font, Color color, String letter,
double startDegree) {
getCoordinates(startDegree);
text = new Text(this.pointX, this.pointY, letter);
text.setTextAlignment(TextAlignment.CENTER);
text.setFont(font);
text.setFill(color);
text.setRotate(this.rotate);
}
/** Sets letter coordinates based on degree */
public void getCoordinates(double degree) {
this.pointX = (this.getWidth() / 2) + circleSize *
Math.cos(Math.toRadians(degree));
this.pointY = (this.getHeight() / 2) + circleSize *
Math.sin(Math.toRadians(degree));
this.pointX -= (this.textFont.getSize() / 3);
this.pointY += (this.textFont.getSize() / 3);
this.rotate = degree + this.textRotate;
}
}
And finally, here is the code for the Circular Text
class which rotates around the center object and yes I know you are thinking, what's the point in having two? Well this one was my original and I decided to try and simplify it, that and I just learned how to animate things so I didn't realize there was a simpler way to rotate text and therefore I was trying to setup the ability to have an EventHandler
redraw the text and in case you was wondering. That's why I probably forgot to remove the getChildren.clear()
. The one below was the first one I wrote and the one above is the second, revised version.
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
/**
* Created by John on 7/11/2014.
*/
public class CircularText extends Pane {
private double circleWidth;
private double circleHeight;
private double textSize;
private double textStartDegree;
private double letterPos;
private double textRotate;
private double gapSpacing;
private double offSetX;
private double offSetY;
private Font font;
private Paint textFill;
private String fontName;
final String text;
/** Default Constructor */
public CircularText(String text) {
this.circleWidth = 250;
this.circleHeight = 250;
this.text = text;
textSize = (this.circleWidth / this.text.length()) * 2;
this.fontName = "Courier New";
this.font = new Font(this.fontName, textSize);
this.textFill = Color.BLACK;
this.textStartDegree = 240;
this.gapSpacing = 0.975;
this.letterPos = 360 / (text.length() / this.gapSpacing);
this.textRotate = 90;
this.offSetX = 4;
this.offSetY = 3;
paintText(this.text, this.font);
}
/** Create Constructor */
public CircularText (String text, double width, double height) {
this.circleWidth = width;
this.circleHeight = height;
this.text = text;
textSize = (this.circleWidth / (this.text.length()) * 2);
this.fontName = "Courier New";
this.font = new Font(this.fontName, textSize);
this.textFill = Color.BLACK;
this.textStartDegree = 240;
this.gapSpacing = 0.975;
this.letterPos = 360 / (text.length() / this.gapSpacing);
this.textRotate = 90;
this.offSetX = 4;
this.offSetY = 3;
paintText(this.text, this.font);
}
/** Get font color */
public Paint getTextFill() {
return textFill;
}
/** Set font color */
public void setTextFill(Paint textFill) {
this.textFill = textFill;
paintText(this.text, this.font);
}
/** Get starting position for text */
public double getTextStartDegree() {
return textStartDegree;
}
/** Set starting position for text */
public void setTextStartDegree(double textStartDegree) {
this.textStartDegree = textStartDegree;
paintText(this.text, this.font);
}
/** Get the placement in degrees of each letter */
public double getLetterPos() {
return this.letterPos;
}
/** Set the placement in degrees of each letter */
public void setLetterPos(double degrees) {
this.letterPos = degrees / (text.length() / this.gapSpacing);
paintText(this.text, this.font);
}
/** Get letter rotation */
public double getTextRotate() {
return textRotate;
}
/** Set letter rotation */
public void setTextRotate(double textRotate, double textFlowControl) {
this.textRotate = textRotate;
setLetterPos(textFlowControl);
paintText(this.text, this.font);
}
/** Get spacing between ending and beginning of phrase */
public double getGapSpacing() {
return gapSpacing;
}
/** Set spacing between ending and beginning of phrase */
public void setGapSpacing(double gapSpacing) {
this.gapSpacing = gapSpacing;
this.letterPos = 360 / (text.length() / this.gapSpacing);
paintText(this.text, this.font);
}
/** Get current font */
public Font getFont() {
return this.font;
}
/** Set new font */
public void setFont(Font font) {
this.font = font;
paintText(this.text, this.font);
}
/** Set new font name */
public void setFont(String name) {
this.fontName = name;
this.font = new Font(this.fontName, textSize);
paintText(this.text, this.font);
}
/** Set font name, text size, offSetX, and offSetY */
public void setFont(String name, double textSize,
double offSetX, double offSetY) {
this.textSize = textSize;
this.offSetX = offSetX;
this.offSetY = offSetY;
this.fontName = name;
this.font = new Font(this.fontName, textSize);
paintText(this.text, this.font);
}
/** Return textSize */
public double getTextSize() {
return this.textSize;
}
/** Set textSize */
public void setTextSize(double textSize, double offSetX,
double offSetY) {
this.textSize = textSize;
this.offSetX = offSetX;
this.offSetY = offSetY;
this.font = new Font(this.fontName, textSize);
paintText(this.text, this.font);
}
/** Return circle's width */
public double getCircleWidth() {
return circleWidth;
}
/** Set circle's width */
public void setCircleWidth(double w) {
this.circleWidth = w;
textSize = (this.circleWidth / this.text.length()) * 2;
paintText(this.text, this.font);
}
/** Return circle's height */
public double getCircleHeight() {
return circleHeight;
}
/** Set circle's height */
public void setCircleHeight(double h) {
this.circleHeight = h;
textSize = (this.circleWidth / this.text.length()) * 2;
paintText(this.text, this.font);
}
/** Paint the Letters */
protected void paintText(String text, Font font) {
getChildren().clear();
// Initialize parameters
double radius = Math.min(circleWidth, circleHeight) * 0.8 * 0.5;
double centerX = this.getWidth() / 2;
double centerY = this.getHeight() / 2;
// Place text in a circular pattern
int i = 0;
double degree = this.letterPos;
for (double degrees = this.textStartDegree;
i < text.length(); i++, degrees += degree) {
double pointX = centerX + radius *
Math.cos(Math.toRadians(degrees));
double pointY = centerY + radius *
Math.sin(Math.toRadians(degrees));
pointX -= (font.getSize() / 3);
pointY += (font.getSize() / 3);
Text letter = new Text(pointX, pointY,
String.valueOf(text.charAt(i)));
letter.setFont(font);
letter.setFill(this.textFill);
letter.setRotate(degrees + this.textRotate);
getChildren().add(letter);
}
}
}