JavaFX在控件中显示属性 [英] JavaFX Displaying properties in controls

查看:159
本文介绍了JavaFX在控件中显示属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在自己完成Oracle的JavaFX教程。经过多年的摇摆(很久以前),我对新的智能功能很着迷,包括。属性。我很惊讶地看到这些例子(例如: https:// docs。 oracle.com/javafx/2/ui_controls/table-view.htm )不要以我认为正确的方式使用它们。

I'm working through myself Oracle's JavaFX tutorials. After doing Swing for many years (a long time ago) I'm fascinated by the new smart features, incl. properties. I was surprised to see that these examples (e.g: https://docs.oracle.com/javafx/2/ui_controls/table-view.htm) don't use them in a way what I believe to be "proper".

该示例创建一个 Person 类,其属性为字段:

The example creates a Person class with properties as fields:

public static class Person {
    private final SimpleStringProperty firstName;
    ...

但是吸气剂不适用于属性,而是适用于它们的值

But the getters are not for the properties, but for their values

    public String getFirstName() {
        return firstName.get();
    }

所以当它绑定到 TableCell s在列中,它将它们包装在一个新属性中:

so when it binds those to TableCells in columns, it wraps them in a new property:

    emailCol.setCellValueFactory(
            new PropertyValueFactory<Person, String>("firstName"));

这对我来说似乎很复杂,并且错过了事件传播的真正优势,不仅仅是使用它:

This seems convoluted to me, and misses the real advantage of event propagation, by not simply using this:

    firstNameCol.setCellValueFactory( celldata -> 
        celldata.getValue().firstNameProperty());

我的问题:这个例子没有公开和使用的原因控件中bean的属性直接?我在这里遗漏了什么吗?

My question: Is there a reason why this example doesn't expose and use the bean's properties in the control directly? Am I missing something here?

注意:我确实以这种方式更改了代码,示例效果更好: Person中的更新其他控件的实体立即传播,没有调用 table.refresh()例如

NB: I did change the code this way, and the example worked much nicer: updates in the Person entity by an other control were propagated immediately, w/o calling table.refresh() e.g.

推荐答案

首先,请注意,如果您按照预期模式

First, note that if you follow the expected pattern:

public class Person {

    private final StringProperty firstName = new SimpleStringProperty();

    public StringProperty firstNameProperty() {
        return firstName ;
    }

    public final String getFirstName() {
        return firstNameProperty().get();
    }

    public final void setFirstName(String firstName) {
        firstNameProperty().set(firstName);
    }
}

然后您的代码版本无需调用 table.refresh()。这是 PropertyValueFactory 的预期用途,从文档

then either version of your code will work without calling table.refresh(). This was the intended use of PropertyValueFactory, as is fairly clear from the documentation.

你是正确的,lambda表达式是比 PropertyValueFactory 更好的方法。除了引用的原因之外,在 PropertyValueFactory 上使用lambda表达式还有其他主要优点。首先,最重要的是, PropertyValueFactory 只需将属性的名称作为 String ,这意味着没有编译时检查它。因此,如果您拼错了该属性的名称:

You are correct, though, that the lambda expression is a better approach than the PropertyValueFactory. Besides the reasons you cite, there are other major advantages to using the lambda expression over PropertyValueFactory. First, and most importantly, the PropertyValueFactory simply takes the name of the property as a String, meaning that there is no compile-time check for it. So if you were to misspell the name of the property:

firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstname"));

这样编译得很好,你最终会在列中找到空白单元格。这可能很难调试(正如本网站上的问题数量所证明的那样,需要帮助解决这类错误:例如 Javafx PropertyValueFactory没有填充Tableview

this would compile just fine, and you would simply end up with blank cells in the column. This can be quite hard to debug (as is evidenced by the number of questions on this site asking for help with this kind of bug: e.g. Javafx PropertyValueFactory not populating Tableview).

其次, PropertyValueFactory 反射工作,比lambda表达慢得多。这可能导致可衡量的性能差异,例如在对包含大量数据的表进行排序时。

Secondly, the PropertyValueFactory works by reflection, which is much slower than a lambda expression. This can lead to measurable performance differences, for example in sorting a table with a large amount of data.

原因 PropertyValueFactory 被介绍基本上是历史的。在Java 8之前,当然没有lambda表达式,所以没有这个便利类的单元工厂的最小实现是通过匿名内部类:

The reason PropertyValueFactory was introduced is basically historical. Prior to Java 8, there were of course no lambda expressions, so the minimal implementation of the cell factory without this convenience class was via an anonymous inner class:

firstNameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(TableColumn.CellDataFeatures<Person, String> cellData) {
        return cellData.getValue().firstNameProperty();
    }
});

由于该代码非常可怕,JavaFX团队引入了 PropertyValueFactory 只是一种使API更易于使用的方法。

Since that code is really quite hideous, the JavaFX team introduced the PropertyValueFactory simply as a way to make the API easier to use.

使用Java 8及更高版本时, PropertyValueFactory 应该被认为是遗留类,而lambda表达式应该是首选。当然,早于Java 8的文档仍然存在(实际上,您明确地链接了JavaFX 2中的文档 - 尽管最新版本仍然没有更新),并且 - 坦率地说 - 太多其他作者没有正确地复制这种风格思考它。完全弃用 PropertyValueFactory 类可能有一个很好的例子。

When using Java 8 and later, PropertyValueFactory should really be considered a legacy class, and the lambda expression should be preferred. Of course, documentation that predates Java 8 also still exists (in fact, you explicitly link documentation from JavaFX 2 - though the most recent version still hasn't been updated), and there are - to be frank - far too many other writers who copy that style without properly thinking it through. There is probably a good case to be made for deprecating the PropertyValueFactory class entirely.

(所以:TL; DR :不,你没有遗漏任何东西。)

(So: TL;DR: no, you're not missing anything.)

这篇关于JavaFX在控件中显示属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆