2014-11-08 2 views
1

JavaFX를 사용할 프로토 타입을 모델링하고 있습니다.일부 외부 이벤트 후 javafx/jrubyfx 장면 전환

응용 프로그램은 셀프 서비스를 위해 키오스크와 유사합니다. 그러나 클라이언트가 상호 작용하기 전에 관리자는이를 잠금 해제해야합니다. 관리자는 전용 채널 (HTTP 또는 IPC 또는 USB 장치)을 통해 일부 원격 명령을 보낼 수 있습니다. 명령의 예는 다음과 같습니다. 시작, 중지 및 재설정

어떻게해야합니까?

a) 다른 스레드에서 실행중인 작업을 IPC를 능동적으로 풀링하고 거기에 메시지가 있으면 장면을 전환 할 수 있습니까?

b) 스레드에서 반응기를 작동시키고 곧 명령을 받으면 JavaFX 스레드로 전달합니다.

두 가지 옵션이 모두 유효합니까? 세 번째로 존재합니까?

답변

1

Task 인 (a) 스레드와 (b) 작업이없는 스레드가 모두 유효합니다. (작업없이 스레드)

내가 옵션 B를 선택하는 것입니다 솔루션 권장

.

솔루션의 핵심 부분은 라인 :

Platform.runLater(() -> MyApplication.changeScene(newData)); 

작업이 좋은,하지만 당신은에 의해 시작 무언가가 있다면 아마 가장 상황에

작업이 좋다 UI 또는 JavaFX 스레드. 예를 들어 사용자가 버튼을 클릭하고 해당 작업을 기반으로 서버에서 데이터를 검색하고 데이터가 검색되면 진행률 보고서를 메시지 및 진행률 막대 업데이트를 통해 피드백하려고합니다. 그래서 작업은 메시지 피드백과 진행 업데이트뿐만 아니라 작업이 시작되고 완료 될 때 잘 정의 된 상태 모델과 같은 사항을 명시 적으로 지원하므로 작업의 종류에 매우 적합합니다. 작업이 이러한 상황을 어떻게 개선하는지 이해하려면 invariants 코드 예제를 참조하십시오. Platform.runLater and Task in JavaFX.

그러나 이벤트의 시작자가 JavaFX 응용 프로그램 스레드에서 벗어난 경우 전통적인 동시성 유틸리티를 사용하는 것보다 Task를 사용하는 것이 많은 이점이 없습니다. 이는 일반적으로 진행 및 메시지 업데이트 API 및 상태 시스템과 같이 태스크가 제공하는 추가 서비스가 필요하지 않기 때문입니다. 또한 이러한 이벤트를 시작하는 라이브러리에는 일반적으로 이미 자체 스레드 모델 설정이 있으므로 작업에서 제공하는 추가 스레딩 프레임 워크가 필요하지 않습니다. Platform.runLater를 사용

()

당신이 정말로 원하는 모든 일이 일어난 알림입니다. 이제 다른 스레드를 사용하여 활성 장면의 항목을 조작 할 수 없으므로 JavaFX 응용 프로그램 스레드에서 알림을 수행해야합니다. JavaFX 응용 프로그램 스레드로 전달되는 이벤트를 얻으려면 Platform.runLater(runnable) 구조를 사용합니다.

샘플 코드

때문에 나는 내가 정말 할 수없는, 루비를 쓰지 않습니다, 그러나 여기에서 당신에게 요점을주는 자바의 일부 코드는 - 실제로 정말 간단합니다.

class DataReader implements Runnable { 
    private final DataSource dataSource; 

    public DataReader(String location) { 
     dataSource = new DataSource(location); 

     Thread thread = new Thread(this); 
     thread.setDaemon(false); 
     thread.start(); 
    } 

    public void run() { 
     while (dataSource.hasData()) { 
      MyImmutableObject newData = dataSource.getSomeData(); 
      Platform.runLater(() -> MyApplication.changeScene(newData)); 
     } 
    } 
} 

class MyApplication extends Application { 
    public void changeScene(MyImmutableObject newData) { 
     FXMLLoader loader = new FXMLLoader(
      getClass().getResource(
       "layout.fxml" 
      ) 
     ); 

     UIController controller = 
      loader.<UIController>getController(); 
     controller.initData(newData); 

     Scene scene = new Scene((Pane) loader.load()); 
     stage.setScene(newScene); 
    } 
} 

위의 예제는 가상의 데이터 소스, MyImmutableObject 및 UIController 클래스와 개념을 설명하기 위해 가상의 FXML 템플릿을 사용한다 (그래서 조각은 독립 실행 가능한 일이 아니다). FXML 로딩 개념은 Passing Parameters JavaFX FXML에서 가져옵니다. 샘플 코드는 자체 스레드를 만듭니다. 그러나 사용하고있는 라이브러리가 이미 스레드 자체를 만드는 경우 (가능성이 높음) 다른 라이브러리를 만들 필요는 없으며 Platform.runLater를 사용하여 기존 라이브러리에 적절한 후크를 추가 할 수 있습니다 이벤트 알림을 얻고 라이브러리 스레드와 JavaFX 응용 프로그램간에 데이터를 전달하는 호출. 작업 대에 StackOverflow에 Platform.runLater에 수많은 다른 질문이 있습니다

관련 질문 :

추가 질문

필자의 경우, 관리자는 경우에 따라 (초기화 벡터와 유사하게) 여권 번호와 같은 초기 정보를 키오스크에 보낼 수 있습니다. 이 정보를 통해 여전히 Platform.runLater가 가장 좋은 솔루션입니까?

예, 여전히 Platform.runLater가 최상의 솔루션입니다. 관리자가 정보를 키오스크 (예 : 임베디드 http 서버 또는 jax-rs 서비스의 서블릿)로 보낼 때 경고되는 스레드가 있으며 Platform.runLater를 호출하여 JavaFX 기반 키오스크 UI를 업데이트 할 수 있습니다 정보.

+0

안녕하세요, 훌륭하고 자세한 내용입니다. 그러나 나는 질문이 있습니다 : 당신이 말한 "당신이 정말로 원한다는 것은 어떤 일이 일어난 사실을 알려주는 것입니다."라고 말했지만, 제 경우에는 관리자가 어떤 경우에는 키오스크에 초기 정보를 보낼 수 있습니다. 초기화 벡터) (예 : 여권 번호). 이 정보를 통해 여전히 Platform.runLater가 가장 좋은 솔루션입니까? –