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();
}
}
당신이 볼 수 있듯이, 코드는 주 스레드에서 호출,이 코드를 호출하는 올바른 장소입니까, 아니면 대화 상자에서 호출해야합니까?
'tarefaPadrao.processar()'와'tarefa.processar()'는 무엇을합니까? 이러한 함수에 대한 코드를 제공 할 수 있습니까? 또는 문제를 나타내는 [sscce] (http://sscce.org/) (많은 코드를 게시하는 것이 더 좋음)입니까? UI 요소 또는 UI 요소에 바인딩 된 모든 JavaFX 응용 프로그램 스레드를 업데이트하려고합니다 (불법입니다)? 귀하의 질문에 대화가 언급되어 있지만 게시 된 코드에 스테이지가 표시되는 코드는 없습니다. – jewelsea
스레드 덤프를 가져 오거나 일식에서 스레드를 일시 중지하십시오. –
@ jewelsea 'tarefaPadrao.processar()'및 'tarefa.processar()'는 일부 dll 코드를 호출합니다. 대화에 대해 물어 보았습니다. 환경을 명확하게하기 위해 질문을 업데이트했습니다 ... – brevleq