2013-09-04 24 views
6

ListViewにはPOJOがいっぱいあり、GUIのラベルには選択した項目の情報が表示されます。ListViewから選択した項目にJavaFX Labelをバインドする方法

私のPOJOは、次のようになります。ユーザーは、私がラベルに表示された選択した顧客の名前をしたいリストから顧客を選択し、今

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

明らかに、nameにはPropertyではないため、私は直接バインドできません。 (SimpleStringPropertyserializableではないと私はCustomerは、RMI経由で転送する必要があるので、私は私の顧客StringProperty -objectsとString Sを交換する必要はありません。)

私が見えた(JFXtrasからBeanPathAdapterを試してみましたこのような)経由で本当にいい:

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(...)を使用し、そこにラベルの人口を手動で処理するよりも良い解決策があることを期待していました。

+0

パートは、アクセス制限の実装は(ように見えるですアダプターはそれを処理できません)。別のバグや無効な期待(私も同様に:-) - 値の更新は、バインドされたプロパティから適応されたプロパティ(つまり、パス)の方向にのみ発生するように見えますが、他の方法ではありません。最低でも豆の中では最も簡単なものではなく、fx-プロパティも普通のコアJava beanプロパティもありません。 – kleopatra

答えて

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()); 
+0

それは非常に有望に見えます。私は今日それを試してみましょう。ありがとう! (遅く返事を申し訳ありません!) –

+0

魅力的な作品です!ありがとう!! –

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が呼び出された場合、そのプロパティは変更を反映しません。お客様の名前が変更されない場合は、この問題を解決することができます。

関連する問題