2014-05-21 25 views
9

Belirli değerleri hesaplamak için JavaFX NumberBindings kullanıyorum. Başlangıçta her şey beklendiği gibi çalışır. Bununla birlikte, oldukça az bir süreden sonra, bağlanma sadece çalışmayı durdurur. Ben de bir İstisna almıyorum.JavaFX Fasulye Bağlama aniden çalışmayı durdurur

Çeşitli bağlamaları yanı sıra yüksek ve düşük düzey yaklaşımları denedim. Hesaplamanın kendisi (geçersiz kılındığında) bile durur ve artık aranmaz. Ayrıca en son JDK (1.8.0_05) güncellemelerini yaptım ve her şeyi yeniden oluşturdum/yeniden başlattım.

Aşağıdaki Minimal Çalışma Örneği sorunu gösterir. Ana pencerenin geçerli genişliğini STDOUT olarak System.out.println yapmalıdır. Pencereyi yaklaşık 10 saniye yeniden boyutlandırdıktan sonra, çıkış sadece durur. Mülkün sürekli kullanımını sağlamak için ortaya çıkan mülkiyeti bir JavaFX kontrolüne bağlamayı denedim, ama bu hiçbir faydası olmadı. Buradaki Mülk/Bağlanmaların bazı çok temel davranışlarını kaçırdığına inanıyorum, Google bu davranışı hiç bilmiyor gibi görünüyor.

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

Sorunu yeniden oluşturabilirim. Bir böcek gibi görünüyor. Jira'yı aradınız mı? – assylias

+0

Mevcut hata raporlarını bulamıyorum. Çok basit bir şey gibi görünüyor, JDK/JRE'nin kendisinde bir hata olduğunu düşünmek zor. – underkuerbis

cevap

13

bağlama currentWidthPlusTen değerini gözlemlemek için WeakListener kullanır. boundNumberProperty referansı tutmazsanız, start(...) yönteminin çıktığı anda çöp toplama için uygundur. Çöp toplayıcısı devreye girdiğinde, referans tamamen kaybolur ve ciltleme artık çalışmaz.

start(...) yöntemine hattını

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

ekleyin doğrudan bu görmek için. Pencereyi tıklayarak dinleyiciyi "çalışmayı durdur" için zorlayabilirsiniz.

Açıkçası, istediğin bu değil: düzeltme, start(...) çıkışından sonra boundNumberProperty başvurusunu korumaktır. Örneğin:

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); 
    } 

} 

Güncelleme

da bakmak isteyebilirsiniz Bu sorunla çalışan herkes bir üçüncü taraf kitaplığı kullanarak pahasına (bunun için daha temiz bir geçici çözüm sağlar Tomas Mikula en ReactFX, , biraz zaman öğrenmeye ihtiyaç duyacağınız). Tomas bu sorunu ve ReactFX'in this blog ve subsequent post'da nasıl çözdüğünü açıklıyor.

+5

+1 Wow iyi lekeli! – assylias

+0

Çok iyi! Bu benim problemimi çözdü. Java'da otomatik bellek/referans yönetimine güvenme ve güvenme eğilimindeyim. Açıkçası çok fazla: D – underkuerbis

+0

İlginç bir şekilde, çoğu zaman bunu gerçekte herhangi bir şey için kullanırsınız, örnek kodunuzdaki basit testler dışında, sorun gider. Örneğin, bir etiket oluşturursanız ve metninizi "IntegerProperty" öğesine bağlarsanız, etiket etkin bir şekilde referansı tutar ve bu nedenle çöp toplamaz. Sadece ara sıra bu problem gerçek bir senaryoda ortaya çıkıyor, ama çok nadir. –

İlgili konular