【问题标题】:How to bind a JavaFX Label to the selected item from a ListView如何将 JavaFX 标签绑定到 ListView 中的选定项目
【发布时间】:2013-09-07 14:14:50
【问题描述】:

我有一个充满 POJO 的 ListView,并希望在 GUI 中有一个标签来显示来自所选项目的信息。

我的 POJO 看起来像这样:

class Customer {
  private String name;
  ...
  public String getName() {
  return name; 
  }

现在,当用户从列表中选择客户时,我希望所选客户的名称显示在标签中。

显然我不能直接绑定到name,因为它不是Property。 (而且我不想用StringProperty-objects 替换我的客户Strings,因为SimpleStringProperty 不是serializable,我需要通过RMI 传输Customer。)

我已经尝试过来自JFXtrasBeanPathAdapter(顺便说一句,看起来非常不错),如下所示:

    BeanPathAdapter<MultipleSelectionModel> customerBeanPathAdapter;
    customerBeanPathAdapter = new BeanPathAdapter<>(lstCustomers.getSelectionModel());
    customerBeanPathAdapter.bindBidirectional("selectedItem.name", lblCustomerName.textProperty());

但是这个解决方案只会给我一个异常:

...
Caused by: java.lang.IllegalArgumentException: Unable to resolve accessor getSelectedItem
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessor(BeanPathAdapter.java:3062)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessorWithLikelyPrefixes(BeanPathAdapter.java:3022)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.updateMethodHandles(BeanPathAdapter.java:2986)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.<init>(BeanPathAdapter.java:2977)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldBean.performOperation(BeanPathAdapter.java:1348)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldBean.performOperation(BeanPathAdapter.java:1186)
at jfxtras.labs.scene.control.BeanPathAdapter.bindBidirectional(BeanPathAdapter.java:567)
at jfxtras.labs.scene.control.BeanPathAdapter.bindBidirectional(BeanPathAdapter.java:369)
at at.gs1.sync.qm.client.gui.MainWindowController.initialize(MainWindowController.java:61)
... 22 more
Caused by: java.lang.IllegalAccessException: symbolic reference class is not public: class javafx.scene.control.ListView$ListViewBitSetSelectionModel, from jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle
at java.lang.invoke.MemberName.makeAccessException(MemberName.java:512)
at java.lang.invoke.MethodHandles$Lookup.checkSymbolicClass(MethodHandles.java:1113)
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1094)
at java.lang.invoke.MethodHandles$Lookup.findVirtual(MethodHandles.java:626)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessor(BeanPathAdapter.java:3049)
... 30 more

所以我希望有一个比使用lstCustomers.getSelectionModel().selectedItemProperty().addListener(...) 并手动处理标签数量更好的解决方案。

【问题讨论】:

  • 部分问题是访问受限的实现(看起来适配器无法处理它)。另一个可能是错误或无效的期望(我的也是:-) - 值更新似乎只发生在从绑定属性返回到适应属性(即路径)的方向上,而不是相反。至少不能让它与最简单的 bean 一起工作,既不是具有 fx-properties 的也不是具有普通核心 java bean 属性的。

标签: java listview javafx-2 javafx


【解决方案1】:

我不认为您正在寻找一种简单的班轮。
您可以执行以下操作:

label.textProperty().bind( Bindings.selectString( listview.getSelectionModel().selectedItemProperty(), "name" ) );

但是您需要像这样修改您的客户 POJO:

class Customer 
{
    private String name;
    ...
    public String getName() { return name;  }

    public ReadOnlyStringProperty nameProperty()
    {
        return new SimpleStringProperty( name );
    }
}

我不认为这是推荐的,因为预计属性会反映基础数据的变化,而上述内容只会反映调用 nameProperty 时的名称。因此,如果 setName 被调用,该属性将不会反映更改。如果客户名称永远不会改变,那么您可以侥幸逃脱。

【讨论】:

    【解决方案2】:

    我认为,与我之前给出的解决方案相比,一个更好的解决方案是按照您的尝试使用 BeanPathAdapter。
    但是 BeanPathAdapter 需要添加以下属性:

    private final ObjectProperty<B>  beanProp = new SimpleObjectProperty<>();
    {
        beanProp.addListener( new ChangeListener<B>()
        {
            @Override
            public void changed( ObservableValue<? extends B> ob, B oldVal, B newVal )
            {
                setBean( newVal );
            }
        } );
    }
    
    public ObjectProperty<B> beanProperty()
    {
        return beanProp; 
    }
    

    然后在您的代码中,您需要以下内容:

    BeanPathAdapter<Customer>  custBean;
    custBean = new BeanPathAdapter<>( new Customer() );   // empty or any customer
    custBean.bindBidirectional( "name", label.textProperty() );
    custBean.beanProperty().bind( listview.getSelectionModel().selectedItemProperty() );
    

    【讨论】:

    • 这看起来很有希望。我今天会试一试。谢谢! (顺便说一句。抱歉回复晚了!)
    • 像魅力一样工作!谢谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    相关资源
    最近更新 更多