Desenvolví uma classe que implementa as interfaces FocusListener,
ActionListener e KeyListener, mas os métodos focusGained() e
focusLost() não deixam os métodos de ActionListener nem os de
KeyListener serem “percebidos”.
Preciso que os três funcionem da forma adequada, ou seja, seja
“percebido” o pressionamento de teclas ao mesmo tempo que seja
validado cada campo JTextField (na saída de cada um deles), bem como
os botões que foram pressionados.
Alguém poderia ajudar ou explicar por quê o FocusListener “toma” para
si o controle prioritário, não deixando os outros atuarem (é como se
não existissem…) ?
Não escrevi nenhum código para testar o seu problema, mas não vejo porque um evento estaria influenciando em outro. Só pare para pensar uma coisa: será que uma classe que implementa FocusListener, ActionListener e KeyListener não estaria tendo muitas responsabilidades? Cuidado com o [url=http://desciclo.pedia.ws/wiki/Gambi_Design_Patterns]Gambi Design Pattern[/url] [url=http://desciclo.pedia.ws/wiki/Gambi_Design_Patterns#Lone_Wolf]Lone Wolf[/url].
Preciso que estes três eventos sejam detectados, independentemente da ordem em que forem acionados teclado, click de botões ou mudança de campo.
Isso deve-se ao fato que, ao carregar a aplicação, o usuário é forçado a preencher o campo ID; caso seja nulo, menor que 0 ou maior que 9999, não permitir a saída do campo; existe um botão chamado “Sair”, que, a qualquer momento se for clicado, encerra a aplicação (independente de haver preenchido algum campo ou não) e esta mesma condição de saída da aplicação pode ser efetuada ao pressionar a tecla “Esc”.
O que ocorre é que o evento FocusListener dos campos ID e Senha, estão tendo “prioridade” sobre os outros eventos, ou seja: não adianta pressionar “Esc” em circunstância alguma que a aplicação não reconhece este pressionamento de tecla, da mesma forma que clicando-se no botão “Sair”, nada acontece.
Tanto o “Esc” quanto o botão “Sair” são “reconhecidos” depois que os campos ID e Senha estão preenchidos e validados de acôrdo com as regras de negócio.
Será que isso não é possível de se fazer em Java ??? (Já observei aplicações bem mais complexas que isso que estou tentando fazer, mas…)
Agradeço a sua atenção e se puder dar uma ajuda, fico no aguardo de um contato, ok?
Assim que você clicar no botão sair o campo para digitar o ID vai perder o focus (focusLost) que vai acionar o seu evento de validação, assim ele não deixa sair mesmo.
Não sei se resolve mas quando perder o focus procure ver se a tecla “Esc” ou o botão esta acionado e sair.
Copiei o código abaixo lá do link mencionado. Funciona desde que eu não coloque o KeyListener…
Dá uma olhada abaixo: coloquei o KeyListener, implementei os respectivos métodos necessários, mas não funciona até que eu tenha preenchido o primeiro campo com “pass” e pressinado “Tab” para passar para o segundo campo…
Será que não tem jeito dos dois funcionarem juntos?
Atenciosamente,
Augusto Cesar
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
// This program demonstrates the use of the Swing InputVerifier class.
// It creates two text fields; the first of the text fields expects the
// string "pass" as input, and will allow focus to advance out of it
// only after that string is typed in by the user.
public class VerifierTest extends JFrame implements KeyListener{
public VerifierTest() {
JTextField tf1 = new JTextField ("Type \"pass\" here");
getContentPane().add (tf1, BorderLayout.NORTH);
tf1.setInputVerifier(new PassVerifier());
JTextField tf2 = new JTextField ("TextField2");
getContentPane().add (tf2, BorderLayout.SOUTH);
WindowListener l = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
addWindowListener(l);
}
class PassVerifier extends InputVerifier {
public boolean verify(JComponent input) {
JTextField tf = (JTextField) input;
return "pass".equals(tf.getText());
}
}
public void keyPressed (KeyEvent key)
{
int p_codigo = key.getKeyCode();
if (p_codigo == 27)
System.exit(0);
}
public void keyTyped (KeyEvent key)
{
}
public void keyReleased (KeyEvent key)
{
}
public static void main(String[] args) {
Frame f = new VerifierTest();
f.pack();
f.setVisible(true);
}
}
Registrar um ActionListener em cada campo também não é a maneira correta de fazer um frame fechar ao se pressionar esc.
A maneira correta é manipular o InputMap e o Actionmap do seu RootPane. Abaixo, um código de exemplo:
[code]//Registramos o listener que faz o frame fechar
Action actionListener = new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
closeDialog();
}
};
//Registramos o listener no ActionMap e KeyMap do RootPane
InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(“ESCAPE”), “ESCAPE”);
rootPane.getActionMap().put(“ESCAPE”, actionListener);[/code]
Você pode fazer isso no construtor do seu JFrame. A vantagem é que você só faz isso uma vez e funciona para tudo o que estiver sobre o RootPane.