This basically it sets a shapes default size and radius based on how many characters are in a string that is passed to it, the user gets the option to manually set the Font, otherwise it is automatically set for them. All letters are set to face towards the center of the circle as it wraps around. I do seem to have two minor flaws in the algorithm, the circular text is slightly offset from the circle object to the right I think and so I have to manually adjust the padding around the sides based on the size of the circle generated.
Another flaw is that as more text is placed in the circle the beginning and end doesn't have consistent spacing with the rest of the sentence, it has a bit of an extra gap which seems to get slightly bigger as more characters are placed in the circle.
If you look at the picture on the right, just noticed this, some of the letters are slightly offset just by a few pixels:
Now I was only required to manually enter the positions of each letter, but I decided to go above and beyond so I would have reusable code for future projects.
/** Main */
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
/**
* Created by John on 7/11/2014.
*/
public class Prog14_05 extends Application {
@Override
public void start(Stage primaryStage) {
// Create Pane
circularText phrase = new circularText("WE ARE ANONYMOUS ",
480, 480);
phrase.setFont("Matrix");
phrase.setTextSize(30);
// Place clock and label in border pane
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
pane.setPadding(new Insets(15, 30, 30, 0));
pane.setStyle("-fx-background-color: black");
pane.getChildren().add(phrase);
// Create a scene and place it in the stage
Scene scene = new Scene(pane);
primaryStage.setTitle("Exercise14_05");
primaryStage.setScene(scene);
primaryStage.show();
}
}
/** circularText class */
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
/**
* Created by John on 7/11/2014.
*/
public class circularText extends Pane {
double textSize = 30;
String string = "";
String fontName = "";
Font font = new Font("Times Roman", textSize);
// Pane's width and height
private double w = 250, h = 250;
/** Create Constructor */
public circularText (String phrase, double w, double h) {
this.w = w;
this.h = h;
this.string = phrase;
textSize = (this.w / this.string.length()) * 2;
paintText(this.string, this.font);
}
/** Set new font */
public void setFont(String name) {
Font font = new Font(name, textSize);
this.font = font;
this.fontName = name;
paintText(this.string, this.font);
}
/** Return textSize */
public double getTextSize() {
return this.textSize;
}
/** Set textSize */
public void setTextSize(double textSize) {
this.textSize = textSize;
Font font = new Font(fontName, textSize);
this.font = font;
paintText(this.string, this.font);
}
/** Return pane's width */
public double getW() {
return w;
}
/** Set pane's width */
public void setW(double w) {
this.w = w;
textSize = (this.w / this.string.length()) * 2;
paintText(this.string, this.font);
}
/** Return pane's height */
public double getH() {
return h;
}
/** Set pane's height */
public void setH(double h) {
this.h = h;
textSize = (this.w / this.string.length()) * 2;
paintText(this.string, this.font);
}
/** Paint the Letters */
protected void paintText(String phrase, Font font) {
// Initialize parameters
double clockRadius = Math.min(w, h) * 0.8 * 0.5;
double centerX = w / 2;
double centerY = h / 2;
// Draw circle
Circle circle = new Circle(centerX, centerY, clockRadius);
circle.setFill(null);
circle.setStroke(null);
getChildren().clear();
getChildren().add(circle);
// Place text in a circular pattern
int i = 0;
double degree = 360 / phrase.length();
for (double degrees = 0; i < phrase.length(); i++, degrees += degree) {
double pointX = circle.getCenterX() + circle.getRadius() *
Math.cos(Math.toRadians(degrees));
double pointY = circle.getCenterY() + circle.getRadius() *
Math.sin(Math.toRadians(degrees));
Text letter = new Text(pointX, pointY, phrase.charAt(i) + "");
letter.setFont(font);
letter.setFill(Color.LIME);
letter.setRotate(degrees + 90);
getChildren().add(letter);
}
}
}