Disparar o focusLost e cancelar o FocusGained [Resolvido de outra maneira, mas resolvido]

8 respostas
V

Pessoal, preciso que, quando um componente vai perder o foco, caso ele não esteja validado, o foco volte pra ele, mas sem passar para o outro componente, entenderam?

É que o FocusGained do outro componente tem código que não deveria ser executado caso o primeiro campo não estivesse validado. Então não posso dar um simples requestFocus, alguém tem alguma idéia que possa me ajudar?

8 Respostas

M
event.consume();
V

Mark_Ameba, a classe java.awt.event.FocusEvent não tem o método consume();

consume() é definido AWTEvent, mas o acesso à ela é protegido. O FocusEvent não permite que esse método seja invocado. Se eu fizer cast para o tipo AWTEvent isso funcionaria? ou o evento de foco não pode ser consumido?

V

O cast não funciona né! Mudar o tipo não resolve o problema…
Apenas classes do pacote podem acessá-lo, o que eu posso fazer existe uma alternativa pra isso?

M

Ahh… nao tinha reparado nisso.

Voce pode acessar por Reflection mas acho inviavel.

Talvez voce pode pensar em outra solução.

L

Oi,

Trambique:

Caso o componente não esteja validado, lancar uma exceção (criado por vc) do tipo: NoFocusChangeSignException que irá ser tratada para dar um requestFocus no componente atual de conteudo não valido.

No FocusGained do outro componente, verifique se ocorreu uma exceção anterior. Se sim, não faz nada. Se não, faz o que deveria ser feito.

Tchauzin!

V

Pois é lina, eu estava evitando os trambiques, heheheehe
Ainda mais esses que eu tenho que implementar no código no FocusGained…
É que eu tenho uma classe que faz essa validação baseada em código que eu passo pra ele o evento e uma condição pra que ele analise, com isso eu economizo muito código…
Esse trambique que você sugeriu é melhor do que alguns que eu tinha pensado… Se não houver outro jeito, fico com ele mesmo, heheheehe

V

O que a acontece é o seguinte, essa classe de validação tem um HashMap com Component e Mensagem(String), tenho um método verifica, onde eu passo a condição, o evento e a mensagem. Esse método é invocado quando o componente perde o foco.
Se a condição for verdadeira, significa que eu tenho um erro então adiciono o componente junto com a mensagem no HashMap. E volto o foco pro componente que gerou o evento.
O Problema: Se :cry: Se o próximo componente for um componente que também tem um verificaErro no focusLost, ele ganha o foco,e é invalidado (pinta a borda de vermelho e mostra uma mensagem em um label), então um campo que ainda nem recebeu dados é considerado como errado…
Não é um problema muito sério já que o usuário vai passar por lá novamente, mas não era exatamente isso que eu queria…

V

Resolvi de outra maneira,
Realmente não consegue cancelar o evento, me parece que o consume() apenas pode ser utilizado em InputEvent, e ele consume o evento mesmo, tipo, se vc cancela um tipo de InputEvent, os ouvintes do seus InputEvent deixam de receber os evento, me corrijam se eu estiver errado.

Então inventei uma gambiarrazinha na minha classe, se interessar a alguém:

package zcm.swing;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.HashMap;
import java.util.Set;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

/**
 *
 * @author Desenvolvimento
 */
public class ZErrorLabel extends javax.swing.JLabel {

    private Border bordaNormal;
    private Border bordaErro;
    private boolean isInValidation=false;

    private HashMap<JComponent,String> listaErros;//HashMap com os componentes mapeando as mensagens - (sem ordem)
   

    private FocusListener focusListener;

    public void setBordaErro(Border bordaErro) {
        this.bordaErro = bordaErro;
    }

    public void setBordaNormal(Border bordaNormal) {
        this.bordaNormal = bordaNormal;
    }

    public ZErrorLabel() {
        super();
        configuraZErrorLabel();
    }

    public ZErrorLabel(Icon image) {
        super(image);
        configuraZErrorLabel();
    }

    public ZErrorLabel(Icon image, int horizontalAlignment) {
        super(image, horizontalAlignment);
        configuraZErrorLabel();
    }

    public ZErrorLabel(String text) {
        super(text);
        configuraZErrorLabel();
    }

    public void configuraZErrorLabel(){
                initComponents();
        listaErros = new HashMap<JComponent, String>();
        focusListener = new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                    ZErrorLabel.this.setText(listaErros.get(e.getSource()));
                    isInValidation=false;
                }
            };
        //Define bordas padrões
        bordaErro = new LineBorder(new Color(255, 100, 100));
        bordaNormal = (new JTextField()).getBorder();
    }



    public boolean componenteTemErro(JComponent c){
        return listaErros.get(c) != null;//Retorna se o erro associado ao componente é nulo
    }

    public String addError(JComponent componente, Component opositeComponente, String mensagem) {
    
        if (listaErros.containsKey(componente)) {
            return "Erro já cadastrado";
        } else {
                       isInValidation =true;
            this.setVisible(true);
            this.setText(mensagem);
            String iretorno = listaErros.put(componente, mensagem);
            //c.removeFocusListener(focusListener);//Removo o listener para evitar que exista mais de um            

            //REtira os ouvintes de foco do componente oposto para que o foco volte para o campo sem maiores problemas

            componente.setBorder(bordaErro);
            if (!listaErros.containsKey(opositeComponente)) componente.requestFocusInWindow();//Só requere o foco caso o componente oposto não esteja em
            componente.addFocusListener(focusListener);

            

            return iretorno;
        }

    }

    public void removeAllErrors() {
        Set<JComponent> set = listaErros.keySet();
        for (JComponent c : set) {
            c.setBorder(bordaNormal);
            c.removeFocusListener(focusListener);
            this.setVisible(true);
            this.setText("");
        }
        listaErros.clear();
    }

    public String removeError(JComponent c) {
        if (listaErros.containsKey(c)) {
            c.setBorder(bordaNormal);
            this.setVisible(false);
            String iRetorno = listaErros.remove(c);
            c.removeFocusListener(focusListener);
            if (!(listaErros.isEmpty())) {
                this.setVisible(true);
                this.setText("");
            }
            return iRetorno;
        }
        return "Elemento não adicionado";
    }

    public boolean verificaError(boolean conditionError, JComponent componente, Component opositeComponente, String msg){
       if(isInValidation==false){
 
            this.setText("");
            if (conditionError==true){
                addError(componente,opositeComponente, msg);
                return true;
            }
            removeError(componente);
       }
        return false;
    }


    //False se não houver erros
    public boolean existeErros(){
        if (listaErros.isEmpty()) return false;
        else{
            
        }
        return true;
    }

    public void mostraMensagemPadrao(Component c){
        JOptionPane.showMessageDialog(c, "Existem campos com erros!\nOs campo errados estão destacados, você deve corrigí-los e então tentar salvar novamente.\nVocê pode ver qual é o erro clicando no campo destacado", "Campos Inválidos", JOptionPane.WARNING_MESSAGE);
    }
    
    @SuppressWarnings("unchecked")
                    
    private void initComponents() {

        setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/erroValidacao.png"))); // NOI18N
    }                     

}
Criado 8 de fevereiro de 2010
Ultima resposta 10 de fev. de 2010
Respostas 8
Participantes 3