Saudações a todos.
Bom, já pesquisei bastante na internet, inclusive aqui no fórum, porém não encontrei nenhuma solução para o meu problema.
É o seguinte: Estou desenvolvendo um plugin para o Eclipse e em uma das views desse plugin eu preciso que uma Thread, que fica ouvindo uma porta a todo tempo, altere, sempre que preciso, o conteúdo de um Text Field. Beleza, escrevi as rotinas, validei o funcionamento das outras ações, porém, na hora de alterar o Text Field recebo a seguinte mensagem de erro: "Invalid thread access"
Já vi que isso se deve a uma “trava” do Java para que não haja acesso concorrente e tal, já tentei usar o Display.getDefault().asyncExec passando minha Thread e nada.
Para testar já fiz até o seguinte e não funcionou (Inclusive não entendi porque travou já que é assincrono):
Você não entendeu para que serve o asyncExec. Ele serve para você executar um trecho de código na thread do SWT. Quando você fez isso (criar uma thread dentro do asyncExec) você violou a concepção do asyncExec, já que o trecho de código dentro da thread não está executando dentro da thread do SWT.
Você teria de fazer algo diferente (ou seja, o que costumo chamar de “pensar do avesso”), que seria algo como:
int i; // variável de instância, não variável local
...
while (true) {
Thread.sleep (1000);
Display.getDefault().asyncExec(new Runnable() {
@Override public void run() {
lblStartPrivateChat.setText(String.valueOf(i));
i++;
}
});
}
Ok, talvez eu realmente não tenha entendido o funcionamento do asyncExec mesmo, porém essa solução que vc me passou também não resolve o problema porque a linha de execução fica presa no while e a tela nem termina de carregar, trava tudo!
De qualquer maneira, fica a lição: asyncExec serve para forçar que o código dentro do “run” seja executado na thread da GUI (no seu caso, o SWT). Você deve imaginar uma forma (provavelmente sem um loop infinito) para tratar o que você tem de fazer.
Não se esqueça: se algo não dá certo do jeito que você está forçando a barra, pense AO CONTRÁRIO.
Runnable a = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lblStartPrivateChat.setText(String.valueOf(i));
i++;
Display.getCurrent().asyncExec(this);
}
};
Display.getCurrent().asyncExec(a);
Funciona, mas o sleep, como ta rodando dentro da thread do swt, acaba gerando um atraso na gui prejudicando a escrita nos campos de texto, mudança de foco e etc.
É, o pior é que eu não tenho muito jeito. Preciso ficar a do tempo escutando uma porta e quando vier alguma coisa preciso colocar o conteúdo no textField.
Vou tentar algo com métodos synchronized ou declarar o textField como volatil (dicas de um colega). Se der certo posto aqui
Isso que eu postei com o Thread.sleep foi só um exemplo, não o meu problema de verdade (que não postei devido o tamanho). Nele, não tenho um sleep e sim um loop infinito.