2013-04-05 2 views
-1

JavaFX 2를 처음 사용하고 JavaFX에서 멀티 스레드를 사용하는 데 문제가 있습니다. 내가 직면하고있는 문제는 응용 프로그램이 단순히 정지되고 이유를 찾을 수 없다는 것입니다. 나는 어떤 곳에서 경쟁 조건이 있다고 생각하지만, 나는 그것을 찾을 수 없다. 자바 FX의 설명서를 말한다 , 나는이 "서비스"를 확장하는 클래스를 만든 내가 ") (시작"그것을 실행 해요 :작업을 실행할 때 JavaFx 2 응용 프로그램이 작동하지 않습니다.

public class ProcessadorTarefas extends Service<StatusRetorno>{ 

    private final ITarefa tarefaPadrao=new TarefaVerificarImpressora(); 
    private final ITarefa tarefa; 
    protected Logger logger = LoggerFactory.getLogger(this.getClass()); 

    public ProcessadorTarefas(ITarefa tarefa) { 
     this.tarefa = tarefa; 
    } 

    public void processar() { 
     if(getState()==State.READY) 
      start(); 
     else 
      restart(); 
    } 

    @Override 
    protected Task<StatusRetorno> createTask() { 
     return new Task<StatusRetorno>() { 
      @Override 
      protected StatusRetorno call() throws Exception { 

        /*THE CODE FREEZES HERE*/ 

       StatusRetorno status = tarefaPadrao.processar(); 
       if (status == StatusRetorno.SUCESSO) 
        status = tarefa.processar(); 
       return status; 
      } 
     }; 
    } 
} 

호출하는 클래스 "processar"방법은 onSuceed, onCancelled 및 듣기 onFailed ProcessadorTarefas 클래스의 :

코드가 "전화"방법에 얼어으로, 리스너가 호출되지 않고 주 대화 상자가 표시되지
public abstract class ControladorBase implements IProcessamentoDispatcher, EventHandler<WorkerStateEvent> { 

    @Autowired 
    protected ControladorDialogoMensagem dialogoMensagem; 
    protected ITarefa tarefa; 
    protected String mensagem; 
    protected Set<IProcessamentoListener> listeners = new ConcurrentSkipListSet<IProcessamentoListener>(); 

    protected void executarTarefa(ITarefa tarefa) { 
     executarTarefa(tarefa, null); 
    } 

    protected void executarTarefa(ITarefa tarefa, String mensagem) { 
     this.tarefa=tarefa; 
     this.mensagem=mensagem; 
     despacharProcessamento(StatusProcessamento.INICIADO, null); 
     final ProcessadorTarefas processador=new ProcessadorTarefas(tarefa); 
     processador.setOnSucceeded(this); 
     processador.setOnCancelled(this); 
     processador.setOnFailed(this); 
     processador.processar(); 
    } 

    @Override 
    public void handle(WorkerStateEvent evento) { 
     StatusRetorno status= (StatusRetorno) evento.getSource().getValue(); 
     despacharProcessamento(StatusProcessamento.FINALIZADO,status); 
     if(status==StatusRetorno.SUCESSO) 
      exibirMensagemSucesso(); 
     else 
      exibirMensagemErro(status); 
    } 

    /*UNIMPORTANT CODE*/ 

    private void despacharProcessamento(StatusProcessamento statusProcessamento, StatusRetorno statusRetorno) { 
     for (IProcessamentoListener listener : listeners) 
      listener.processamento(new EventoProcessamento(this, statusProcessamento,statusRetorno)); 
    } 

    /*ADD AND REMOVE LISTENERS CODE*/ 
} 

, 사용자가 로그인 한 후이 코드가 호출이 발생할

합니다. INFORMATION ADDED

로그인 대화 상자를 닫고 주 대화 상자가 열리기 전에, 그래서 화면에있는 자바 FX 요소가없는 후이 코드가 실행 :

public class App extends Application implements IDadosSubmetidosListener, IProcessamentoListener { 

    /*variable declaration ommited*/ 

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

    @Override 
    public void start(Stage stage) throws Exception { 
     ApplicationContext contexto = new ClassPathXmlApplicationContext("/spring/appContext.xml"); 
     App aplicacao = contexto.getBean(App.class); 
     SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL); 
     aplicacao.iniciar(); 
    } 

    private void iniciar() { 
     cancelarOperacoesTEF(); 
     controladorDialogoLogin.adicionarListener(this); 

     /*opens login dialog*/ 

     controladorDialogoLogin.abrir(); 
    } 

    private void verificarDadosEAbrirTelaPrincipal() { 

     /*after the user logged in, close login dialog*/ 

     controladorDialogoLogin.limparListeners(); 
     controladorDialogoLogin.fechar(); 
     if (verificadorFuncaoUsuario.usuarioAutorizado()) { 
      if (verificadorFuncaoUsuario.usuarioCaixa()) 
       verificarSeECFValidoECadastrar(); 
      else 
       controladorDialogoPrincipal.abrir(); 
     } else { 
      controladorDialogoMensagem.adicionarListener(this); 
      controladorDialogoMensagem.exibirAlerta("Você não tem credenciais que te permitam acessar este sistema!"); 
     } 
    } 

    private void verificarSeECFValidoECadastrar() { 
     verificadorNumeroSerieECF.adicionarListener(this); 

     /*this code call that class shown above*/ 

     verificadorNumeroSerieECF.verificarNumeroSerieECF(); 
    } 

    private void terminarCadastroECFEAbrirTelaPrincipal() { 
     controladorDialogoCadastroECF.limparListeners(); 
     controladorDialogoCadastroECF.fechar(); 
     controladorDialogoPrincipal.abrir(); 
    } 
} 

당신이 볼 수 있듯이, 코드는 주 스레드에서 호출,이 코드를 호출하는 올바른 장소입니까, 아니면 대화 상자에서 호출해야합니까?

+0

'tarefaPadrao.processar()'와'tarefa.processar()'는 무엇을합니까? 이러한 함수에 대한 코드를 제공 할 수 있습니까? 또는 문제를 나타내는 [sscce] (http://sscce.org/) (많은 코드를 게시하는 것이 더 좋음)입니까? UI 요소 또는 UI 요소에 바인딩 된 모든 JavaFX 응용 프로그램 스레드를 업데이트하려고합니다 (불법입니다)? 귀하의 질문에 대화가 언급되어 있지만 게시 된 코드에 스테이지가 표시되는 코드는 없습니다. – jewelsea

+0

스레드 덤프를 가져 오거나 일식에서 스레드를 일시 중지하십시오. –

+0

@ jewelsea 'tarefaPadrao.processar()'및 'tarefa.processar()'는 일부 dll 코드를 호출합니다. 대화에 대해 물어 보았습니다. 환경을 명확하게하기 위해 질문을 업데이트했습니다 ... – brevleq

답변

0

Service 클래스가 JavaFX 구성 요소에서 호출 될 때만 작동한다는 것을 알지 못했습니다. 그래서이 문제를 해결하기 위해이 코드 부분을 단일 스레드에서 실행하도록 수정했습니다. 프로그램의 다른 부분에서 서비스는 JavaFX의 구성 요소 (예 : 버튼)에서 시작되며 잘 작동합니다.

관련 문제