如何在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
相关产品推荐
相关产品推荐

