这是一个示例替代实现。
它使用Group
带有layoutChildren
实现而不是绑定 api 的子类。
import javafx.application.Application;
import javafx.beans.property.StringProperty;
import javafx.geometry.VPos;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.*;
import javafx.stage.Stage;
public class TextInRectangle extends Application {
public static void main(String[] args) throws Exception { launch(args); }
public void start(final Stage stage) throws Exception {
TextBox text = new TextBox("All roads lead to Rome", 100, 100);
text.setLayoutX(30);
text.setLayoutY(20);
final Scene scene = new Scene(text, 160, 140, Color.CORNSILK);
stage.setScene(scene);
stage.show();
}
class TextBox extends Group {
private Text text;
private Rectangle rectangle;
private Rectangle clip;
public StringProperty textProperty() { return text.textProperty(); }
TextBox(String string, double width, double height) {
this.text = new Text(string);
text.setTextAlignment(TextAlignment.CENTER);
text.setFill(Color.FORESTGREEN);
text.setTextOrigin(VPos.CENTER);
text.setFont(Font.font("Comic Sans MS", 25));
text.setFontSmoothingType(FontSmoothingType.LCD);
this.rectangle = new Rectangle(width, height);
rectangle.setFill(Color.BLACK);
this.clip = new Rectangle(width, height);
text.setClip(clip);
this.getChildren().addAll(rectangle, text);
}
@Override protected void layoutChildren() {
final double w = rectangle.getWidth();
final double h = rectangle.getHeight();
clip.setWidth(w);
clip.setHeight(h);
clip.setLayoutX(0);
clip.setLayoutY(-h/2);
text.setWrappingWidth(w * 0.9);
text.setLayoutX(w / 2 - text.getLayoutBounds().getWidth() / 2);
text.setLayoutY(h / 2);
}
}
}
示例应用程序的示例输出:
几点注意事项:
通常最好使用 aLabel
而不是尝试重新创建 Label 的部分功能。
方法中的布局layoutChildren
类似于 JavaFX 团队在实现 JavaFX 控件库时使用的布局。他们使用layoutChildren
而不是绑定布局可能是有原因的,但我不知道所有这些原因是什么。
我发现对于简单的布局,最好使用 JavaFX 库中的预构建控件和布局管理器(例如,上述控件可以仅使用 StackPane 中的标签或文本来实现)。如果我无法从内置布局中获得所需的布局,那么我将使用绑定来补充它们的使用,我发现它也很容易使用。我不需要使用layoutChildren
那么多。这可能只是扩展以布置复杂节点组的问题 - 很可能在该layoutChildren
方法中进行计算性能更好,并且在应用于复杂节点组时可能更容易使用和调试。
代码并没有像 a那样Text
通过计算文本大小并从 a 中删除多余的字符来截断,而是调用文本节点以可视方式将其裁剪为矩形的大小。相反,如果您希望截断更像 a ,那么您可以查看JavaFX 实用程序类的代码,该类执行剪切文本的计算。String
Label
setClip
Text
Label
问题中的示例代码无法编译,因为它缺少wrappingWidthProperty
表达式上的括号,并且它在绑定表达式中使用getValue
和getWidth
方法,这是不可能的 - 相反,它需要在boundsInLocalProperty
.
此外,创建了一个小型示例应用程序,演示将放置在具有矩形背景的标签中的文本添加到窗格中,并通过绑定精确控制标记矩形的 x、y 位置。