OpenJFX控件Label与Text的区别

|1933字|547阅读

作者最近关注到腾讯云+社区有一个提问:如何实现JavaFX中的标签和文本差异?

javafx.scene.text.Text和javafx.scene.control.Label有什么区别?

JDK源文件说:Label是一个不可编辑的文本控件(display read-only textual content)。

Text类定义显示文本的节点。

但Label类有一个方法“setText”和“textProperty”,因此是可编辑的。

链接:https://cloud.tencent.com/developer/ask/173589

有以下两个回答:


答者1.

正如Harry Blargle指出的那样,“不可编辑”意味着“不能被用户编辑”,因此Label和Text都是不可编辑的。 标签和文本具有不同的CSS属性, Label继承自Labeled,Control和Region,这意味着它继承了Text没有的许多可定制属性。标签可以具有对齐,图形,背景,边框,显示的键盘助记符,内置包装,并且可以使用省略号(“...”)智能地剪裁。 文本可以参与TextFlow,如果要通过在其旁边放置一个或多个单词来显示输入控件的用途,和/或希望允许直接键盘导航到输入控件,则使用Label。如果要显示与输入无关的文本内容,请使用“Text”。


答者2.

Text是几何形状(如矩形或圆形), 而Label是UI控件(如Button或CheckBox)。 在Swing中,几何形状仅限于绘制机制,而在JavaFX中,可以以更通用的方式使用。


Label

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * Label is a non-editable text control. A Label is useful for displaying
 * text that is required to fit within a specific space, and thus may need
 * to use an ellipsis or truncation to size the string to fit. Labels also are
 * useful in that they can have mnemonics which, if used, will send focus to
 * the Control listed as the target of the ```labelFor``` property.
 * 
 * Label sets focusTraversable to false.
 * 
 *
 * <p>Example:
 * ```Label label = new Label("a label");```
 *   @since JavaFX 2.0
 */

Text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * The {@code Text} class defines a node that displays a text.
 *
 * Paragraphs are separated by {@code '\n'} and the text is wrapped on
 * paragraph boundaries.
 * import javafx.scene.text.*;
 *  
 * Text t = new Text(10, 50, "This is a test");
 * t.setFont(new Font(20));
 *
 *
 *
 * import javafx.scene.text.*;
 *
 * Text t = new Text();
 * text.setFont(new Font(20));
 * text.setText("First row\nSecond row");
 *
 *
 *
 * import javafx.scene.text.*;
 *
 * Text t = new Text();
 * text.setFont(new Font(20));
 * text.setWrappingWidth(200);
 * text.setTextAlignment(TextAlignment.JUSTIFY)
 * text.setText("The quick brown fox jumps over the lazy dog");
 * @since JavaFX 2.0
 */


继续搜索stackoverflow发现了以下问题与上面的问题类似

有三个回答:

A:

As Harry Blargle pointed out, "non-editable" means "not editable by the user." So both Label and Text are non-editable.

Label and Text have different CSS properties. Label inherits from Labeled, Control, and Region, which means it inherits a great many styleable properties which Text doesn't have. A Label can have alignment, a graphic, a background, a border, a displayed keyboard mnemonic, built-in wrapping, and can be intelligently clipped with an ellipsis ("…").

Text can participate in a TextFlow. (Technically, Label can also, but it is treated as just another embedded control and is not laid out as text.)

In general, if you want to show the purpose of an input control by placing one or more words next to it, and/or you want to allow direct keyboard navigation to an input control, you use a Label. If you want to display text content not associated with input, you use Text.


B:

A Text is a geometric shape (like a Rectangle or a Circle), while Label is a UI control (like a Button or a CheckBox).

In Swing, geometric shapes were restricted to the painting mechanism, while in JavaFX they can be used in more generic ways.


C

  • Labels

    • A label displays text or image which the user cannot directly change or edit . Especify the image for the label.

      标签显示用户无法直接更改或编辑的文本或图像。指定标签的图像

  • TextFields

    • A TextField displays text or image which the user can directly change or edit .. don't specify image for the text field.

    TextField 显示用户可以直接更改或编辑的文本或图像。 不要为文本字段指定图像

*** 其中前两个与上面两个回答是相同的,即为上面问题回答的出处。第三个用简单的两句话描述出了Label与Text两个控件的最明显区别。但好像把TextField与Text搞混淆了***


更新Lable标签抛出异常的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

  @FXML 
  private Text timer;  

  @Override 
  public void initialize(URL url, ResourceBundle rb) {    
     init();  
  
     new Thread() {
      public void run() {          
         while(true) {               
            Calendar cal = new GregorianCalendar();                
            int hour = cal.get(cal.HOUR);                
            int minute = cal.get(cal.MINUTE);              
            int second = cal.get(cal.SECOND);               
            int AM_PM = cal.get(cal.AM_PM);                
            String time = hour + "" + minute + "" + second;          
            timer.setText(time);           
          }      
       }   
     }.start();
 } 



// ---------------------------------------------------------------------------------------------------------


Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4 at com.sun.javafx.tk.Toolkit.checkFxUserThread(Unknown Source) 
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(Unknown Source) 
at javafx.scene.Scene.addToDirtyList(Unknown Source) 
at javafx.scene.Node.addToSceneDirtyList(Unknown Source) 
at javafx.scene.Node.impl_markDirty(Unknown Source) 
at javafx.scene.shape.Shape.impl_markDirty(Unknown Source) 
at javafx.scene.Node.impl_geomChanged(Unknown Source) 
at javafx.scene.text.Text.impl_geomChanged(Unknown Source) 
at javafx.scene.text.Text.needsTextLayout(Unknown Source) 
at javafx.scene.text.Text.needsFullTextLayout(Unknown Source) 
at javafx.scene.text.Text.access$200(Unknown Source) 
at javafx.scene.text.Text$2.invalidated(Unknown Source) 
at javafx.beans.property.StringPropertyBase.markInvalid(Unknown Source) 
at javafx.beans.property.StringPropertyBase.set(Unknown Source) 
at javafx.beans.property.StringPropertyBase.set(Unknown Source) 
at javafx.scene.text.Text.setText(Unknown Source) 
at uy.com.vincent.fx.handling.TableController$1.run(TableController.java:70) 

将 timer.setText() 包裹在 Platform.runLater() 中。在它之外,在 while 循环内,添加 Thread.sleep(1000); Illegal State Exception 背后的原因是您试图在 JavaFX 应用程序线程以外的某个线程上更新 UI。 您的应用程序在添加时崩溃的原因是您通过添加要在 UI 线程上无限执行的进程来使 UI 线程过载。让线程休眠 1000 毫秒将帮助您解决这个问题。 如果可能,将 while(true) 替换为 Timer 或 TimerTask。 有关更多选项,请点击此链接


1.Not on FX application thread; currentThread =

需要在用户线程中更新Lable的属性时采用如下方式

1
2
3
4
     Platform.runLater(() -> {
       //  更新Label属性
       currentDateTimeLabel.setText(text);
    });

参考案例( https://www.cnblogs.com/miaoqx/articles/13729178.html )很简单,创建了一个VBox,然后分别在1和2处添加一个Label和一个TextField。如果打开注释3,那么会报如上错误信息。解决办法就是用注释4处的方法。 那么是不是所有的类似add, addAll等方法都需要使用Platform.runLater(() -> {//TODO});处理呢?参考注释1,2,你会发现其实不是这样的。 这里有一个一个判断标准:

如果这一行代码运行之后,页面的UI会发生肉眼可见的变化,那么就需要使用Platform.runLater处理。否则的话不用。

总结

  • Label与Text的区别

    • Label标签显示用户无法直接更改或编辑的文本或图像。指定标签的图像,修改时需要Platform.runLater()方法中使用Label的setText方法修改text属性,改变Label显示的文本值。
    • Text 显示用户可以直接更改或编辑的文本。可直接调用Text控件的setText方法修改text属性。
  • Label的实现方式

Label继承自Labeled,Control和Region,这意味着它继承了Text没有的许多可定制属性。标签可以具有对齐,图形,背景,边框,显示的键盘助记符。

Labeled中的setText方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    /* *************************************************************************
     *                                                                         *
     * Properties                                                              *
     *                                                                         *
     **************************************************************************/
    /**
     * The text to display in the label. The text may be null.
     *
     * @return the text to display in the label
     * @defaultValue empty string
     */
    public final StringProperty textProperty() {
        if (text == null) {
            text = new SimpleStringProperty(this, "text", "");
        }
        return text;
    }
    private StringProperty text;
    public final void setText(String value) { textProperty().setValue(value); }




// ------------------------------------------
//  javafx.beans.property.SimpleStringProperty.java

    /**
     * The constructor of {@code StringProperty}
     *
     * @param bean
     *            the bean of this {@code StringProperty}
     * @param name
     *            the name of this {@code StringProperty}
     * @param initialValue
     *            the initial value of the wrapped value
     */
    public SimpleStringProperty(Object bean, String name, String initialValue) {
        super(initialValue);
        this.bean = bean;
        this.name = (name == null) ? DEFAULT_NAME : name;
    }

  • Text的实现方式

Text是几何形状(如矩形或圆形)


相关链接


|1933字|547阅读
         
返回顶部