You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaFX中让可移动文本保持在窗口内并居中?

解决方案

1. 文本初始居中与自适应调整

要让文本初始居中,需在UI渲染完成后计算容器与文本的尺寸差,设置文本位置。如果需要窗口 resize 时保持居中,可以进一步绑定位置属性到容器尺寸变化事件。

2. 阻止文本移出边界

在按钮点击事件中,计算新的X坐标并限制范围:

  • 左边界:文本左边缘不能小于0
  • 右边界:文本右边缘(文本X坐标 + 文本宽度)不能超过容器宽度

修正后的完整代码

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.scene.paint.Color;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.application.Platform;

public class Text extends Application {
    @Override
    public void start(Stage stage) {
        Pane paneText = new Pane();
        Text text = new Text("I'm editable");
        paneText.getChildren().addAll(text);

        HBox paneButton = new HBox(10);
        paneButton.setAlignment(Pos.TOP_CENTER);
        Button bt1 = new Button("<");
        Button bt2 = new Button(">");
        paneButton.getChildren().addAll(bt1, bt2);

        HBox paneRadioButton = new HBox(10);
        paneRadioButton.setAlignment(Pos.BASELINE_LEFT);
        RadioButton rbRed = new RadioButton("Red");
        RadioButton rbBlue = new RadioButton("Blue");
        RadioButton rbBlack = new RadioButton("Black");
        RadioButton rbOrange = new RadioButton("Orange");
        RadioButton rbGreen = new RadioButton("Green");

        ToggleGroup gr = new ToggleGroup();
        rbRed.setToggleGroup(gr);
        rbBlue.setToggleGroup(gr);
        rbBlack.setToggleGroup(gr);
        rbOrange.setToggleGroup(gr);
        rbGreen.setToggleGroup(gr);

        paneRadioButton.getChildren().addAll(rbRed, rbBlue, rbBlack, rbOrange, rbGreen);

        BorderPane pane = new BorderPane();
        pane.setCenter(paneText);
        pane.setTop(paneButton);
        pane.setBottom(paneRadioButton);

        // 延迟执行确保UI渲染完成,计算初始居中位置
        Platform.runLater(() -> {
            double centerX = (paneText.getWidth() - text.getBoundsInLocal().getWidth()) / 2;
            double centerY = (paneText.getHeight() - text.getBoundsInLocal().getHeight()) / 2;
            text.setX(centerX);
            text.setY(centerY);
        });

        // 左移按钮,限制左边界
        bt1.setOnAction(e -> {
            double newX = text.getX() - 10;
            if (newX >= 0) {
                text.setX(newX);
            }
        });

        // 右移按钮,限制右边界
        bt2.setOnAction(e -> {
            double textWidth = text.getBoundsInLocal().getWidth();
            double paneWidth = paneText.getWidth();
            double newX = text.getX() + 10;
            if (newX + textWidth <= paneWidth) {
                text.setX(newX);
            }
        });

        rbRed.setOnAction(e -> text.setFill(Color.RED));
        rbBlue.setOnAction(e -> text.setFill(Color.BLUE));
        rbBlack.setOnAction(e -> text.setFill(Color.BLACK));
        rbOrange.setOnAction(e -> text.setFill(Color.ORANGE));
        rbGreen.setOnAction(e -> text.setFill(Color.GREEN));

        Scene scene = new Scene(pane, 400, 250);
        stage.setTitle("Text");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

额外说明

  • 修正了原代码中的变量名错误:paneButtons→paneButton、paneRadioButtons→paneRadioButton、paneeli→pane
  • 使用Platform.runLater避免因UI未渲染完成导致的尺寸计算错误
  • 边界判断考虑了文本自身宽度,确保整个文本始终在容器可见范围内

内容的提问来源于stack exchange,提问作者Anna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:37:53