2013-09-04 2 views
6

ListView에 POJO가 가득 찼으며 GUI의 레이블에 선택한 항목의 정보가 표시되기를 원합니다.ListView에서 선택한 항목에 JavaFX Label을 바인딩하는 방법

내 POJO는 다음과 같은 : 사용자가 내가 레이블에 표시 선택한 고객의 이름을 원하는 목록에서 고객을 선택 이제

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

.

이 아니기 때문에 분명히 name에 바인딩 할 수 없습니다. (그리고 SimpleStringPropertyserializable하지 않기 때문에 나는 StringProperty -objects 내 고객 String의를 교체하지 않고 나는 Customer가 RMI를 통해 옮겨진 될 필요가있다.) 나는 어떤 보이는 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

파트 액세스 제한 구현합니다 (처럼 보이는 어댑터가 처리 할 수 ​​없음). 다른 하나는 버그이거나 잘못된 기대 일 수 있습니다. (물론 광산도 있습니다 :-) - 값 업데이트는 바인딩 된 속성에서 다시 적응 된 속성 (즉, 경로)으로 향하는 방향으로 만 발생하는 것으로 보입니다. 적어도 bean의 가장 단순한 것, fx-property 나 평범한 핵심 자바 빈 속성을 가진 것은 아니었다. – kleopatra

답변

2

필자가 이전에 한 것보다 나은 해결책은 시도한 것처럼 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는 다음과 같은 특성이 추가되어 있어야 문제의

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

매우 유망 해 보입니다. 나는 오늘 그것을 시도 할 것이다. 감사! (btw. 답장 늦어서 미안 해요!) –

+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을 호출하면 속성에 변경 내용이 반영되지 않습니다. 고객 이름이 변경되지 않으면이 문제를 해결할 수 있습니다.

관련 문제