2014-05-21 2 views
9

특정 값을 계산하기 위해 JavaFX NumberBinding을 사용합니다. 처음에는 모든 것이 예상대로 작동합니다. 그러나 약간의 시간이 지나면 바인딩이 작동을 멈 춥니 다. 나는 예외도받지 못한다.JavaFX Beans Binding이 갑자기 작동하지 않습니다.

필자는 고수준 접근법과 저수준 접근법을 비롯하여 몇 가지 바인딩을 시도했습니다. 계산 자체 (오버라이드 된 경우)조차도 중지되고 더 이상 호출되지 않습니다. 또한 최신 JDK (1.8.0_05)로 업데이트하고 모든 것을 재 빌드/다시 시작했습니다.

다음 최소 작동 예제에서이 문제를 설명합니다. System.out.println은 메인 윈도우의 현재 너비를 STDOUT으로 설정해야합니다. 약 10 초 동안 창 크기를 조정하면 출력이 멈 춥니 다. 또한 프로퍼티의 지속적인 사용을 보장하기 위해 JavaFX 컨트롤에 결과 속성을 바인딩하려고 시도했지만 아무 소용이 없습니다. 나는 Property/Bindings의 아주 기본적인 행동을 여기에서 놓치고 있다고 생각한다. Google은 그 행동을 전혀 모르는 것 같다.

import javafx.application.Application; 
import javafx.beans.binding.NumberBinding; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class BindingsProblem extends Application { 

@Override 
public void start(Stage primaryStage) { 
    // Initialization... 
    StackPane root = new StackPane(); 
    Scene scene = new Scene(root, 300, 250); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 


    // Binding - The problem occurrs here! 
    NumberBinding currentWidthPlusTen = primaryStage.widthProperty().add(10); 
    IntegerProperty boundNumberProperty = new SimpleIntegerProperty(); 
    boundNumberProperty.bind(currentWidthPlusTen); 
    boundNumberProperty.addListener(new ChangeListener<Number>() { 

     @Override 
     public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
      System.out.println(newValue.toString()); 
     } 

    }); 
} 


public static void main(String[] args) { 
    launch(args); 
} 

} 
+0

문제가 재현 될 수 있습니다. 그것은 마치 버그처럼 보입니다. 지라를 조사해 봤어? – assylias

+0

기존 버그 리포트를 찾을 수없는 것 같습니다. JDK/JRE 자체의 버그라고 상상하기가 너무 근본적인 것 같습니다. – underkuerbis

답변

13

바인딩은 currentWidthPlusTen 값을 관찰하기 위해 사용 WeakListener. boundNumberProperty에 대한 참조를 유지하지 않으므로 start(...) 메소드가 종료 되 자마자 가비지 수집 대상이됩니다. 가비지 수집기가 시작되면 참조가 완전히 손실되고 바인딩이 더 이상 작동하지 않습니다.

start(...) 방법에 선

root.setOnMousePressed(event -> System.gc()); 

을 추가, 직접를 참조하십시오. 창을 클릭하여 청취자가 "작동을 멈추게"할 수 있습니다.

분명히 그게 당신이 원하는 것이 아닙니다. 수정은 start(...) 종료 후에 boundNumberProperty에 대한 참조를 유지하는 것입니다. 예를 들면 :

import javafx.application.Application; 
import javafx.beans.binding.NumberBinding; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class BindingsProblem extends Application { 

    IntegerProperty boundNumberProperty; 

    @Override 
    public void start(Stage primaryStage) { 
     // Initialization... 
     StackPane root = new StackPane(); 
     Scene scene = new Scene(root, 300, 250); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

     // Binding - The problem occurrs here! 
     NumberBinding currentWidthPlusTen = primaryStage.widthProperty() 
       .add(10); 

     boundNumberProperty = new SimpleIntegerProperty(); 
     boundNumberProperty.bind(currentWidthPlusTen); 
     boundNumberProperty.addListener(new ChangeListener<Number>() { 

      @Override 
      public void changed(ObservableValue<? extends Number> observable, 
        Number oldValue, Number newValue) { 
       System.out.println(newValue.toString()); 
      } 

     }); 

    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

} 

업데이트

도보고 할 수 있습니다 이러한 문제가 누구 타사 라이브러리를 사용하는 비용 (이것에 대한 청소기 해결 방법을 제공합니다 토마스 Mikula의 ReactFX, , 당신은 약간의 시간을 학습을 보내야 할 것입니다). Tomas는이 문제와 ReactFX가 this blogsubsequent post에서 어떻게 해결하는지 설명합니다.

+5

+1 우물 발견! – assylias

+0

아주 좋습니다! 이것은 내 문제를 해결했다. 필자는 Java의 자동 메모리/참조 관리를 신뢰하고 의존하는 경향이 있습니다. 분명히 너무 많습니다. D – underkuerbis

+0

흥미롭게도 대부분의 경우 샘플 코드의 간단한 테스트 유형 외에는 실제로이 코드를 사용합니다. 문제는 사라집니다. 예를 들어, 레이블을 생성하고 그 텍스트를 'IntegerProperty'에 바인딩하면 레이블은 사실상 참조를 속성으로 유지하므로 가비지 수집을하지 않습니다. 때때로이 문제는 실제 시나리오에서 나타나지만 매우 드뭅니다. –

관련 문제