Estou aqui tentando resolver um problema relacionado ao foco de uma aplicação. A lógica do foco é a seguinte:
Existem dois tipos de ordenação (para troca de foco) possíveis:
1 - O foco navega na ordem em que os componentes foram inseridos no container
2 - O foco navega seguindo uma ordem aleatória definida pelo programador. Nesse modelo cada componente deve saber qual é o componente que está posicionado antes e depois dele.
Alguns campos ficam desabilitados na tela e só passam a estar habilitados de acordo com uma lógica estabelecida por outro campo. Por exemplo: eu tenho um campo nota fiscal e um campo fornecedor. O campo fornecedor não pode ser informado sem que uma nota tenha sido informada e validada. Na lógica do sistema, o campo nota fiscal começa habilitado e o campo fornecedor desabilitado. O campo fornecedor só vai ser habilitado quando o campo nota for informado e validado. Não sei se chega a ser relevante, mas as validações são feitas baseadas no InputVerifier. 70% das telas do sistema tem esse tipo de comportamento.
Tenho uma implementação de FocusTraversalPolicy que permite que a ordem do foco seja mantida de acordo com o “esperado”.
Meu problema, quando minha implementação de FocusTransversalPolicy tenta ordenar esses dois campos (nota fiscal e fornecedor) ela descobre que o campo fornecedor é o próximo, mas não o elege como o próximo, pois ele ainda está desabilitado… acaba elegendo outro, quando o foco prossegue o campo fornecedor habilita mas o foco já foi para outro lugar…
Alguém tem alguma idéia de como posso resolver esse problema?
Espero que tenha conseguido ser claro o suficiente.
Andei fazendo umas pesquisas e cheguei a duas possíveis soluções:
Invocar o processo de validação dentro do transferFocus dos meus componentes, assim poderei “adiantar” o processo e garantir que o componente eleito pela minha FocusTransversalPolicy é o componente que pode receber o foco. Acho que essa funciona, mas não sei se é seguro/recomendado modificar esse comportamento.
Ao invés de tornar meu campo desabilitado vou tentar torná-lo não editável. Não sei se isso vai resolver, vou testar e ver o que acontece. Não sei se vai funcionar, pois ao torná-lo não editável terei que adicionar essa regra à minha política de foco e pode ser que o mesmo problema ocorra novamente.
Envolve habilitar/desabilitar determinados campos juntamente com o processo de foco.
O que eu preciso:
Tenho uma tela T.
Dentro dessa tela eu tenho três campos: A, B e C.
Os campos A e C estão sempre habilitados.
O campo B fica desabilitado e só habilita quando o conteúdo de A for válido.
O conteúdo de A será valido de acordo com uma regra que coloquei dentro de um InputVerifier. Após validar o campo A, eu disparo um listener (que acabei criando aqui) que permite atualizar o estado de todos os componentes que dependem do campo A. Assim o campo B fica sabendo que o conteúdo do campo A é válido e habilita para edição.
O foco deve começar no campo A. Ao sair desse campo o foco deve ir para o campo B se estiver habilitado ou para o campo C caso o campo B estiver desabilitado.
O fluxo que verifiquei ocorre mais ou menos assim:
Campo A vai perder o foco
A FocusTranversalPolicy deve indicar qual é o próximo componente que receberá o foco
O componente eleito sofrerá um requestFocus
A validação do campo A será executada. Se for executada com sucesso o foco vai para o campo eleito, do contrário fica no campo com conteúdo considerado inválido.
Meu problema é que ao invocar a FocusTransversalPolicy o campo B ainda está desabilitado, pois a validação do campo A ainda não foi executada. Logo, a minha policy indica que o campo C deve receber o foco… daí o campo C recebe um requestFocus que dispara a validação do campo A. O campo A é validado e notifica os ouvintes, habilitando o campo B, mas o foco já foi enviado para o campo C.
não foi muito hehe mas eu entendi porque não está dando certo…o que eu não entendi é porque você não pode habilitar um campo antes de chamar o método que escolhe o foco
O problema é que não sou eu quem chama a validação nem a mudança de foco. Eu não mexi nesses eventos… Eu apenas escrevi um InputVerifier e coloquei no componente e escrevi uma lógica para identificar que é o próximo a receber o foco… quando esses meus dois componentes serão invocados não está sob o meu controle… é o java quem está controlando isso…
Depois de muito pesquisar e fuçar… acabei invertendo o processo padrão:
1 - Descobrir quem será o próximo a receber o foco
2 - Executar a validação de quem estava com o foco
3 - Mandar o foco para o componente descoberto no item 1
para:
1 - Executar a validação de quem estava com o foco
2 - Descobrir quem será o próximo a receber o foco
3 - Mandar o foco para o componente descoberto no item anterior…
Não sei se é uma boa solução… mas resolve o meu problema…
Fico grato pela atenção que tiveram com meu problema…