2012-05-15 3 views
2

나는 초를 수백 번 업데이트하는 Java FX 2 앱이 있습니다. 라벨이 부분적으로 잠깐 동안 공백으로 표시되는 경우 문제가 발생하지만 이는 매우 자주 발생합니다. 어떻게 해결할 수 있습니까?JavaFX 2 빈 라벨 새로 고침 문제

enter image description here

+0

제 생각 엔 JavaFX 이벤트 큐를 넘치게하거나 JavaFX 응용 프로그램 스레드에서 UI를 업데이트하는 것 같습니다. 덜 자주 업데이트 해 보셨습니까? (예를 들어, 슬로우 모션 카메라에서 UI를 다시 재생하지 않는 한 <30 초 =>>, 초당 수 백 회 발생하면 아무도 업데이트를 볼 수 없습니다. JavaFX 펄스 메커니즘은 기본적으로 60fps로 제한됩니다.). 업데이트 빈도를 줄이지도 문제가 해결되지 않으면 짧은 실행 가능한 데모 앱을 게시하면 답을 얻을 수 있습니다. – jewelsea

+0

나는 그것을 할 수있는 쉬운 방법이 있다면 조절을 시도 할 수는 있지만 확실하지는 않습니다. Platform.runLater를 사용하여 업데이트를 수행합니다. –

답변

1

두 번째는 좋은 생각이 아니다 배의 Platform.runLater() 수백 호출. Platform.runLater()를 호출하여 Platform.runLater가 초당 30 회 이상 호출되지 않도록 UI를 업데이트하기 전에 Platform.runLater()를 호출하기 전에 데이터 소스의 입력 속도를 줄이거 나 데이터를 배치하는 것이 좋습니다.

jira 요청 RT-21569을 제출하여 Platform.runLater 호출에 대한 문서를 개선하고 기본 플랫폼에 우수한 runLater 이벤트 조절 시스템을 구현하는 것을 고려했습니다.

runLater 이벤트를 일괄 처리하기위한 샘플 솔루션은 Richard Bair가 forum thread에 제공합니다. 참조 된 포럼 스레드에서 복사 리처드 베어에 의해

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.control.ListView; 
import javafx.stage.Stage; 

import java.util.LinkedList; 
import java.util.List; 
import java.util.concurrent.Semaphore; 

/** 
* 
*/ 
public class BackgroundLoadingApp extends Application { 

    private ListView<String> listView; 

    private List<String> pendingItems; 

    private Semaphore lock = new Semaphore(1); 

    protected void addItem(String item) throws InterruptedException { 
     if (Platform.isFxApplicationThread()) { 
      listView.getItems().add(item); 
     } else { 
      // It might be that the background thread 
      // will update this title quite frequently, and we need 
      // to throttle the updates so as not to completely clobber 
      // the event dispatching system. 
      lock.acquire(); 
      if (pendingItems == null) { 
       pendingItems = new LinkedList<String>(); 
       pendingItems.add(item); 
       Platform.runLater(new Runnable() { 
        @Override public void run() { 
         try { 
          lock.acquire(); 
          listView.getItems().addAll(pendingItems); 
          pendingItems = null; 
         } catch (InterruptedException ex) { 
          ex.printStackTrace(); 
         } finally { 
          lock.release(); 
         } 
        } 
       }); 
      } else { 
       pendingItems.add(item); 
      } 
      lock.release(); 
     } 
    } 

    /** 
    * The main entry point for all JavaFX applications. 
    * The start method is called after the init method has returned, 
    * and after the system is ready for the application to begin running. 
    * <p/> 
    * <p> 
    * NOTE: This method is called on the JavaFX Application Thread. 
    * </p> 
    * 
    * @param primaryStage the primary stage for this application, onto which 
    *      the application scene can be set. The primary stage will be embedded in 
    *      the browser if the application was launched as an applet. 
    *      Applications may create other stages, if needed, but they will not be 
    *      primary stages and will not be embedded in the browser. 
    */ 
    @Override public void start(Stage primaryStage) throws Exception { 
     listView = new ListView<String>(); 
     primaryStage.setScene(new Scene(listView)); 
     primaryStage.show(); 

     // Start some background thread to load millions of rows as fast as it can. But do 
     // so responsibly so as not to throttle the event thread 
     Thread th = new Thread() { 
      @Override public void run() { 
       try { 
        for (int i=0; i<2000000; i++) { 
         addItem("Item " + i); 
         if (i % 200 == 0) { 
          Thread.sleep(20); 
         } 
        } 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }; 
     th.setDaemon(true); 
     th.start(); 
    } 

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

댓글 :

여기에 데이터의 풍부한 양을 생산하는 일부 긴 실행 스레드를 시뮬레이션 한 예이다. 나는 그것이 내 취향에 맞지 않는다는 것을 알았다. Thread.sleep가 없으면 여전히 프로세스를 습격합니다 (이 경우 동시성을 처리하는 방식 일 수 있습니다). 나는 또한 자면서 "2"ms로 줄이면 스크롤 막대 엄지 손가락을 움켜 잡고 움직일 수 없었다. 여기서 문제는 언론과 드래그의 이벤트 큐에 마우스 이벤트가 있다고 생각하지만 드래그 이벤트 사이에 새 항목이 목록에 추가되어 엄지 손가락이 움직이게되고 내 드래그 이벤트보다 더 자주 발생하기 때문에 내가 원하는 곳으로 가지 마라. 이것은 엄지 손가락 위치가 행 수를 기반으로 처리되는 방식 때문이라고 생각합니다. 여기서는 내가 수행하는 것처럼 추가되는 행을 스로틀 및 일괄 처리하기위한 애플리케이션을 제외하고 수행 할 수있는 작업에 대해 확신 할 수 없습니다.

+0

그 스레드에 대한 대답을 찾을 수 없습니다 ... 유일한 대답은 스레드로드를 생성합니다 ... 이상적이지 않습니다. –

+0

참조 된 스레드의 샘플 솔루션을 내 대답으로 복사했습니다. 이 솔루션은 Richard Bair가 만들었지 만 내가 작성한 것은 아닙니다. – jewelsea