我目前正在尝试在Java应用程序中的圆圈中创建一系列字符。从本质上讲,短语“欢迎来到Java”将放置在一个圆圈中,从最右边开始用W.当字符沿着圆圈向下移动时,它们以一种方式旋转,使得字母的底部面向内部,按顺序形成一个圆圈。
我的代码似乎可以适当地旋转字符,但它们不会出现在窗格中心以外的任何位置。所以我的问题是:如何使用javafx实用程序将字母远离窗格中心?我的代码如下:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.geometry.Pos;
public class Characters extends Application{
@Override
public void start (Stage primaryStage){
//Create the pane
GridPane pane = new GridPane();
pane.setPrefSize(600, 600);
pane.setAlignment(Pos.CENTER);
//Font class instance
Font font = Font.font("Times New Roman", FontWeight.BOLD, FontPosture.REGULAR, 35);
//Welcome to Java string
String welcome = "Welcome to Java";
double rotation = 90;
double x = Math.cos(rotation)*100;
double y = Math.sin(rotation)*100;
//Loop
for (int i = 0; i < welcome.length(); i++){
x = Math.cos(Math.toRadians(rotation));
y = Math.sin(Math.toRadians(rotation));
System.out.println("Y: " + y);
System.out.println("X: " + x);
Text text = new Text(x, y, welcome.charAt(i)+"");
System.out.println("Actual X" + text.getX());
System.out.println("Actual Y" + text.getY());
text.setFont(font);
text.setRotate(rotation);
pane.getChildren().add(text);
rotation += 22.5;
}
//Create the scene for the application
Scene scene = new Scene(pane, 500, 500);
primaryStage.setTitle("Characters around circle");
primaryStage.setScene(scene);
//Display
primaryStage.show();
}
public static void main (String [] args){
launch(args);
}
}
答案 0 :(得分:1)
GridPane
基本上会忽略你的定位并决定它自己的孩子的位置。在这种情况下,所有Text
元素都放在column=0; row=0)
GridPane
的“单元格”的中心。
我个人更喜欢将Text
节点放在Group
中,并将Group
添加到父布局,而不是将其放在具有复杂布局算法的Parent
中。
使用a Rotate
transform更容易实现旋转,因为这允许您指定旋转的轴心点:
@Override
public void start(Stage primaryStage) {
//Create the pane
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
Group textGroup = new Group();
//Font class instance
Font font = Font.font("Times New Roman", FontWeight.BOLD, FontPosture.REGULAR, 35);
//Welcome to Java string
String welcome = "Welcome to Java";
double rotation = 90;
double radius = 100d;
//Loop
for (char c : welcome.toCharArray()) {
// ignore whitespace, otherwise add rotated char
if (!Character.isWhitespace(c)) {
Text text = new Text(Character.toString(c));
text.setFont(font);
Rotate rotationMatrix = new Rotate(rotation, 0, radius);
text.getTransforms().add(rotationMatrix);
textGroup.getChildren().add(text);
}
rotation += 22.5;
}
pane.getChildren().add(textGroup);
//Create the scene for the application
Scene scene = new Scene(pane, 500, 500);
primaryStage.setTitle("Characters around circle");
primaryStage.setScene(scene);
//Display
primaryStage.show();
}
答案 1 :(得分:0)
这会让你更接近你想要的结果。那里有几个错误。你不应该在这里使用GridPane,因为它的布局会干扰你的文字放置,你的公式也是错误的。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Characters extends Application {
@Override
public void start(Stage primaryStage) {
// Create the pane
// GridPane pane = new GridPane();
Pane pane = new Pane();
pane.setPrefSize(600, 600);
// pane.setAlignment(Pos.CENTER);
// Font class instance
Font font = Font.font("Times New Roman", FontWeight.BOLD, FontPosture.REGULAR, 35);
// Welcome to Java string
String welcome = "Welcome to Java";
double rotation = 90;
double offset = pane.getPrefWidth() / 2;
double radius = 100;
double x = offset + Math.cos(rotation) * radius;
double y = offset + Math.sin(rotation) * radius;
// Loop
for (int i = 0; i < welcome.length(); i++) {
x = offset + Math.cos(Math.toRadians(rotation)) * radius;
y = offset + Math.sin(Math.toRadians(rotation)) * radius;
System.out.println("Y: " + y);
System.out.println("X: " + x);
Text text = new Text(x, y, welcome.charAt(i) + "");
System.out.println("Actual X" + text.getX());
System.out.println("Actual Y" + text.getY());
text.setFont(font);
text.setRotate(rotation);
pane.getChildren().add(text);
rotation += 22.5;
}
// Create the scene for the application
// Scene scene = new Scene(pane, 500, 500);
Scene scene = new Scene(pane);
primaryStage.setTitle("Characters around circle");
primaryStage.setScene(scene);
// Display
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
答案 2 :(得分:0)
您可以使用PathTransition执行此操作,但文本没有字距调整。所以角色看起来不太好看,我也不得不插入一些空格。也许其他一些会让它变得更好。
但作为一个不错的附加组件,如果您对该行timer.start();
发表评论,那么该文字将围绕该圈旋转。
import javafx.animation.*;
import javafx.application.Application;
import javafx.collections.*;
import javafx.scene.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
public class BezierTextPlotter extends Application {
private static final String CIRCLE_TEXT = " Welcome to Java ";
@Override
public void start(final Stage stage) throws Exception {
final Text text = new Text(CIRCLE_TEXT);
text.setStyle("-fx-font-size: 40px");
Circle circle = new Circle(200, 200, 100);
final ObservableList<Text> parts = FXCollections.observableArrayList();
final ObservableList<PathTransition> transitions
= FXCollections.observableArrayList();
for (char character : text.textProperty().get().toCharArray()) {
Text c = new Text(character + "");
c.setEffect(text.getEffect());
c.setStyle(text.getStyle());
parts.add(c);
transitions.add(createPathTransition(circle, c));
}
AnchorPane ap = new AnchorPane();
ap.getChildren().addAll(parts);
for (int i = 0; i < parts.size(); i++) {
final Transition t = transitions.get(i);
t.stop();
t.jumpTo(Duration.seconds(10).multiply((i + 0.5) * 1.0 / parts.size()));
AnimationTimer timer = new AnimationTimer() {
int frameCounter = 0;
@Override
public void handle(long l) {
frameCounter++;
if (frameCounter == 1) {
t.stop();
stop();
}
}
};
timer.start();
t.play();
}
stage.setTitle("Circle Text Sample");
stage.setScene(new Scene(ap, 400, 400, Color.ALICEBLUE));
stage.show();
}
private PathTransition createPathTransition(Shape shape, Text text) {
final PathTransition trans
= new PathTransition(Duration.seconds(10), shape, text);
trans.setAutoReverse(false);
trans.setCycleCount(PathTransition.INDEFINITE);
trans.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
trans.setInterpolator(Interpolator.LINEAR);
return trans;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
行timer.start()
注释: