2015-02-02 5 views
1

JavaFX에서 연결된 속성이나 상호 의존적 속성을 구현하는 가장 좋은 방법은 무엇입니까?연결된 속성을 구현하는 JavaFX

예를 들어 나는 세 개의 정수 특성, lower, upper 및 그 range = upper - lowerrange하고 범위를 설정하려고하면 그것은 또한 (lower + range에) 위 설정에 의해 표현하고 싶은 간격을 가지고있다.

이것은 전통적인 Java Beans (set/get 메소드)에서 간단하지만 JavaFX 속성에는 Observable 개념과 Bindings가 포함되어있어 복잡 해지는 것으로 보입니다.

바인딩을 시도했지만 대상 속성을 설정할 수 없으며 양방향 바인딩도되지만 '같음'만 바인딩 할 수 있습니다.

range을 구현 한 트랙을 javafx.beans.property.IntegerProperty으로 시작했지만 리스너를 처리하는 등의 작업이 많은 것처럼 보입니다.

더 간단한 방법이 있나요?

편집 : 이는 자바 빈즈 패턴을 사용하는 것입니다 무엇 :

private int lower = 0; 
private int upper = 0; 

public int getLower() { 
    return lower; 
} 
public void setLower(int lower) { 
    this.lower = lower; 
} 

public int getUpper() { 
    return upper; 
} 
public void setUpper(int upper) { 
    this.upper = upper; 
} 

public int getRange() { 
    return upper - lower; 
} 
public void setRange(int range) { 
    upper = lower + range; 
} 

이 어떻게 자바 FX의 방법으로이 작업을 수행 할 것입니까? 여기에 내가 일을 생각하지만, ChangeListeners에 추가가 게으른 평가를 사용하는 기회를 파괴 나는 '더미'속성을 정의해야하며 (내가 생각하는)

IntegerProperty lower = new SimpleIntegerProperty(this, "lower", 0); 
IntegerProperty upper = new SimpleIntegerProperty(this, "upper", 0); 
IntegerProperty range = new SimpleIntegerProperty(this, "range", 0); 

public LinkedPropTest() { // Constructor 
    lower.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> { 
     range.setValue(upper.getValue() - lower.getValue()); 
    }); 
    upper.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> { 
     range.setValue(upper.getValue() - lower.getValue()); 
    }); 
    range.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> { 
     upper.setValue(range.getValue() + lower.getValue()); 
    }); 
} 

을 시도거야. 좋아

+0

그래서이 제대로 얻을 : 당신은 세 가지 속성/설정 가능한 독립형 싶지? – eckig

+0

예, 사용자가 바인딩 할 수있는 세 가지 속성이 있지만 두 개의 독립적 인 속성 만 있습니다. –

+0

당신은 예와 아니오 모두에 대답했습니다 ;-) 어느 것이 독립적이어야합니까? 두 명이라고 했니? – eckig

답변

1

, 우리는 필요

  • 두 기본을 SimpleIntegerProperty
  • IntegerProperty 객체와 IntegerPropertyBase에서 파생 된 하나의 정의를 IntegerProperty 사용자의 요구에 특별한 동작을 구현 할 수 있습니다.

그래서 우리는 회원으로 귀하의 속성이 있습니다

private final IntegerProperty lower = new SimpleIntegerProperty(0); 
private final IntegerProperty upper = new SimpleIntegerProperty(0); 
private final IntegerProperty range = new IntegerPropertyBase() { 

    { 
     upper.addListener(obs -> update()); 
     lower.addListener(obs -> update()); 
    } 

    @Override 
    public String getName() { 
     return "range"; 
    } 

    @Override 
    public Object getBean() { 
     return Main.this; 
    } 

    private void update() { 
     super.set(upper.get() - lower.get()); 
    } 

    @Override 
    public void set(int newValue) { 
     upper.set(lower.get() + newValue); 
    } 

}; 

우리의 사용자 지정 속성은 기본적으로 설정할 수있는의 특별한 경우에 관찰 가능한 복합 숫자입니다. 그래서 우리는 몇 가지 메서드를 덮어 썼고 필요한 리스너를 등록했습니다.

그리고 테스트하기 위해 몇 가지 예제 코드 /이를 확인 :

private void printStats() { 
    System.out.println("lower : " + lower.get() + " - upper: " 
      + upper.get() + " - range: " + range.get()); 
    System.out.println(); 
} 

@Override 
public void start(Stage primaryStage) { 

    lower.addListener(obs -> {System.out.println("Lower changed"); printStats();}); 
    upper.addListener(obs -> {System.out.println("Upper changed"); printStats();}); 
    range.addListener(obs -> {System.out.println("Range changed"); printStats();}); 

    System.out.println(" ######### TEST #1 #############"); 
    lower.set(5); 

    System.out.println(" ######### TEST #2 #############"); 
    upper.set(5); 

    System.out.println(" ######### TEST #3 #############"); 
    range.set(10); 
} 
+0

좋아요.WritableIntegerValue에 정의 된 setValue (Number) 메서드를 사용할 때와 변수를 더 바인딩 할 때도 완벽하게 작동한다고 추가합니다 (추가 재정의 없이는 내게 명확하지 않습니다) –

+0

이는 (ab) 'IntegerPropertyBase'를 사용하여 의존성과 리스너를 관리하기위한 보일러 플레이트의 대부분을 수행하는 기본 구현입니다. – eckig

관련 문제