Pessoal, estou tentando fazer alguns Eventos para quando pressionar o ENTER ele clica no “principal” botão do form, o problema é: Ao passar pela tela de login (que possui listeners nos TextFields) ele também está clicando no botão principal do próximo FORM (que é o Registrar). Como faço para evitar esse “conflito”, pois os botões LOGIN e REGISTRAR (de diferentes frames) estão sendo clicados! VALEU!!!
[quote=JoAuM]Pessoal, estou tentando fazer alguns Eventos para quando pressionar o ENTER ele clica no “principal” botão do form, o problema é: Ao passar pela tela de login (que possui listeners nos TextFields) ele também está clicando no botão principal do próximo FORM (que é o Registrar). Como faço para evitar esse “conflito”, pois os botões LOGIN e REGISTRAR (de diferentes frames) estão sendo clicados! VALEU!!!
[/quote]
Ao invés de “addKeyListener(this)”, crie listeners separados para cada coisa. Fica bem mais organizado.[code]private KeyListener listenerSair = new KeyAdapter() {
public void keyPressed(KeyEvent arg0) {
if (!formLogin.isShowing() || arg0.getKeyCode() != KeyEvent.VK_ESCAPE) return;
System.exit(0);
}
};
private KeyListener listenerLogin = new KeyAdapter() {
public void keyPressed(KeyEvent arg0) {
if (!formLogin.isShowing() || arg0.getKeyCode() != KeyEvent.VK_ENTER) return;
formLogin.getButtonLogar().doClick();
}
};
private KeyListener listenerRegistrar = new KeyAdapter() {
public void keyPressed(KeyEvent arg0) {
if (!formLogin.isShowing() || arg0.getKeyCode() != KeyEvent.VK_ENTER) return;
formPrincipal.getButtonRegistrar().doClick();
}
};[/code]Listeners:
formLogin.getButtonLogar().addKeyListener(listenerLogin);
formLogin.getTextFieldLogin().addKeyListener(listenerLogin);
formLogin.getPasswordFieldSenha().addKeyListener(listenerLogin);
formPrincipal.getTextFieldNome().addKeyListener(listenerRegistrar);
formPrincipal.addKeyListener(listenerSair);
formLogin.addKeyListener(listenerSair);
Ah, mais uma coisa, evita usar doClick(). Ao invés disso, chame diretamente o método que o clique vai provocar.
Se seu problema é só ter um botão principal para ser clicado com enter, faça, no seu construtor:
getRootPane().setDefaultButton(getButtonLogar());
Faça o mesmo no outro JFrame para o botão de registrar. Com uma única linha de código, esse comando deixará o botão principal com um desenho mais destacado e fará com que seja automativamente acionado no enter.
Já para o ESC, fica muito melhor se você registrar um InputMap e um ActionMap.
//Mapeamos o botão ESC a ação descrita pela string.
ActionMap amap = getContentPane().getActionMap();
//Mapeia a string para a ação a ser executada.
amap.put(“SairDoPrograma”, new AbstractAction() { @Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}); [/code]
A vantagem é que você só faz isso uma vez, no seu construtor e não precisa ficar adicionando listeners de componente em componente. O que, além de poupar muito trabalho, deixa o código muito mais fácil de manter.
Victor, eu também faço do jeito que vc falou: crio um listener para cada botão, ou tecla. Mas para o caso dos métodos idênticos é uma boa criar uma função separada e fazer todos os métodos chama-la. Assim você evita duplicação de código e torna o programa mais fácil de manter.
Boa tarde novamente!
Utilizei um pouco a idéia de cada um… Quando for default no Form eu uso o getRoot… Já o meu Form principal eu possuo dois scrollPanes dentro de uma tabbedPane ou seja, não posso ter um default naquele form pois quando estou no scroll de consulta, quero que o default seja o botão pesquisa, já quando o scroll for Cadastro quero que o botão seja Registrar mas esse código não funciona assim:
Alguma sugestão? E obrigado pela ajuda anterior, embora os InputMaps eu não tenha conseguido usar, usei o RootPane mesmo, e para tecla ESC usei a primeira sugestão… Vou continuar tentando!
Valeu!
Não dependa de listeners para o ESC. As vezes o foco vai para lugares exotéricos e aí o usuário vai pensar que o ESC deixou de funcionar. Fora que, você vai ter que lembrar de por o listener lá, caso adicione um novo componente.
Tentei colocá-lo na mesma classe onde instacio os forms, onde ficam os listeners e o método dos Action mas ele apresenta vários erros:
ActionMap cannot be resolved to a type, JComponent cannot be resolved entre outros.
public class FormPrincipal extends JDialog {
public FormPrincipal(Frame owner) {
super(owner);
initComponents();
}
public FormPrincipal(Dialog owner) {
super(owner);
initComponents();
}
Colocando aquele código no construtor ele fca pedindo para fazer Casting, diz que tem método não implementado etc etc…
Obs.: Utilizo JFormDesigner para fazer os forms…
Ah, desculpe, é que o getContentPane() retorna um objeto do tipo container. Erro meu.
Troque o getCotentPane() pelo painel principal da sua classe e deve funcionar. Ou faça um cast para JPanel antes.
JPanel painel = (JPanel)getContentPane();
InputMap imap = painel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
imap.put(KeyStroke.getKeyStroke("ESCAPE"), "SairDoPrograma");
//Mapeamos o botão ESC a ação descrita pela string.
ActionMap amap = painel.getActionMap();
//Mapeia a string para a ação a ser executada.
amap.put("SairDoPrograma", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
Deu certo Vinicius, entretanto, não fica estranho eu dar ações dentro da classe Form não? Sempre tive na mente que a interface com o usuário é feita na classe principal! (me corrija se estiver errado!). Agora consigo eliminar o excesso de listeners! Mas aquele velho problema no scrollpane ainda não está resolvido, ou está e não to vendo? hehehehee
Obrigado!!!
[quote=JoAuM]Deu certo Vinicius, entretanto, não fica estranho eu dar ações dentro da classe Form não? Sempre tive na mente que a interface com o usuário é feita na classe principal! (me corrija se estiver errado!). Agora consigo eliminar o excesso de listeners! Mas aquele velho problema no scrollpane ainda não está resolvido, ou está e não to vendo? hehehehee
Obrigado!!![/quote]
Você está completamente errado. De onde você tirou essa idéia?
Professores :lol: .
É costume falarem que o contato com o usuário é feito na classe principal! Ou será que entendi errado?
Não sei se me expliquei mal mas é que, as ações de sair devem passar por uma entrada feita no programa principal, por exemplo, System.exit(0) não cabe à classe do Form fazer e sim ao MAIN. Foi assim que me foi ensinado, mas se não for o correto, mudo agora!
[quote=JoAuM]Professores :lol: .
É costume falarem que o contato com o usuário é feito na classe principal! Ou será que entendi errado?
Não sei se me expliquei mal mas é que, as ações de sair devem passar por uma entrada feita no programa principal, por exemplo, System.exit(0) não cabe à classe do Form fazer e sim ao MAIN. Foi assim que me foi ensinado, mas se não for o correto, mudo agora!
[/quote]
Programa e classe são coisas completamente diferentes, logo “programa principal” e “classe que tem o método main” também são coisas completamente diferentes. Para o usuário, se o programa apresenta a tela com 1 ou 1.000.000 de classes, não faz a menor diferença.
O que você tem que prezar é aqueles velhos conceitos de OO que continuam completamente válidos até hoje, mas que a maior parte do pessoal não entende corretamente: Encapsulamento; Alta coesão e Baixo acoplamento. Estes três conceitos são razoavelmente bons para medir a qualidade do seu sistema. Não tendo isso o sistema sai tosco e cheio de problemas. Tendo isso, o resto (polimorfismo, MVC, padrões de projeto, etc) é conseqüência desses três.