How to close a Jframe using keyboard events?

Asked

Viewed 1,998 times

7

I have a Jframe that I want to close when I press the Esc key...

Well, I did that:

public Cadastro() {
    addKeyListener(this);

And then that:

public void keyTyped(KeyEvent evt) {
    if(evt.getKeyCode() == KeyEvent.VK_ESCAPE){
        dispose();
    }
}  

If you want to see the whole class:

package Classes;

import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

public class Cadastro extends javax.swing.JFrame implements KeyListener{

public Cadastro() {
    initComponents();
    setIcone();
    new Connect().Open();
    addKeyListener(this);
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jLabel1 = new javax.swing.JLabel();
    Título = new javax.swing.JTextField();
    Editora = new javax.swing.JTextField();
    jLabel2 = new javax.swing.JLabel();
    Altor = new javax.swing.JTextField();
    jLabel3 = new javax.swing.JLabel();
    jLabel4 = new javax.swing.JLabel();
    jScrollPane1 = new javax.swing.JScrollPane();
    Comentário = new javax.swing.JTextArea();
    jLabel5 = new javax.swing.JLabel();
    Nota = new javax.swing.JComboBox();
    BotaoEnviar = new javax.swing.JButton();
    BotaoLimpar = new javax.swing.JButton();
    aviso = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    setTitle("Cadastro");
    setResizable(false);
    addWindowListener(new java.awt.event.WindowAdapter() {
        public void windowClosed(java.awt.event.WindowEvent evt) {
            formWindowClosed(evt);
        }
    });

    jLabel1.setText("Título");

    Título.setFont(new java.awt.Font("Microsoft Sans Serif", 0, 11)); // NOI18N

    Editora.setFont(new java.awt.Font("Microsoft Sans Serif", 0, 11)); // NOI18N

    jLabel2.setText("Editora");

    Altor.setFont(new java.awt.Font("Microsoft Sans Serif", 0, 11)); // NOI18N

    jLabel3.setText("Altor(a)");

    jLabel4.setText("Nota");

    Comentário.setColumns(20);
    Comentário.setFont(new java.awt.Font("Microsoft Sans Serif", 0, 11)); // NOI18N
    Comentário.setLineWrap(true);
    Comentário.setRows(5);
    Comentário.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyTyped(java.awt.event.KeyEvent evt) {
            ComentárioKeyTyped(evt);
        }
    });
    jScrollPane1.setViewportView(Comentário);

    jLabel5.setText("Comentários");

    Nota.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "", "1", "2",              "3", "4", "5" }));

    BotaoEnviar.setText("Enviar");
    BotaoEnviar.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            BotaoEnviarActionPerformed(evt);
        }
    });

    BotaoLimpar.setText("Limpar");
    BotaoLimpar.setToolTipText("Limpa os compos de texto.");
    BotaoLimpar.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            BotaoLimparActionPerformed(evt);
        }
    });

    aviso.setFont(new java.awt.Font("Microsoft Sans Serif", 0, 11)); // NOI18N

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(jLabel5)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jScrollPane1)
                    .addContainerGap())
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addGap(0, 0, Short.MAX_VALUE)
                    .addComponent(BotaoEnviar)
                    .addGap(72, 72, 72)
                    .addComponent(BotaoLimpar)
                    .addGap(78, 78, 78))
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel2)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(Editora, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel1)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                            .addComponent(Título, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 20, Short.MAX_VALUE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                            .addComponent(jLabel3)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                            .addComponent(Altor, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel4)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                            .addComponent(Nota, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGap(29, 29, 29))
                .addGroup(layout.createSequentialGroup()
                    .addComponent(aviso)
                    .addGap(0, 0, Short.MAX_VALUE))))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel1)
                .addComponent(Título, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel3)
                .addComponent(Altor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(29, 29, 29)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(Editora, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel2)
                .addComponent(jLabel4)
                .addComponent(Nota, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(51, 51, 51)
                    .addComponent(jLabel5))
                .addGroup(layout.createSequentialGroup()
                    .addGap(18, 18, 18)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(BotaoLimpar)
                .addComponent(BotaoEnviar))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 34, Short.MAX_VALUE)
            .addComponent(aviso))
    );

    pack();
    setLocationRelativeTo(null);
}// </editor-fold>                        

private void BotaoLimparActionPerformed(java.awt.event.ActionEvent evt) {                                            
    Título.setText(null);
    Editora.setText(null);
    Altor.setText(null);
    Comentário.setText(null);
    Nota.setSelectedIndex(0);
    aviso.setText(null);
}                                           

private void BotaoEnviarActionPerformed(java.awt.event.ActionEvent evt) {                                            
    ImageIcon ico = new ImageIcon(Cadastro.class.getResource("/Recursos/check.png"));

    String T = Título.getText();
    String A = Altor.getText();
    String E = Editora.getText();
    String N = "";
    String C = Comentário.getText();

    int select = Nota.getSelectedIndex();

    switch(select){
        case 0: N = "";
        break;
        case 1: N = "1";
        break;
        case 2: N = "2";
        break;
        case 3: N = "3";
        break;
        case 4: N = "4";
        break;
        case 5: N = "5";
        break;
    }

    String query = "insert into tablivros (`Título`, `Altor`, `Editora`, `Comentário`, `Nota`) values ('"+T+"', '"+A+"', '"+E+"', '"+C+"', '"+N+"')";

    new Connect().Execute(query);
    JOptionPane.showMessageDialog(null, "Livro cadastrado com sucesso!", "Cadastro", 0, ico);
}                                           

private void formWindowClosed(java.awt.event.WindowEvent evt) {                                  
    new Connect().Close();
}                                 

private void ComentárioKeyTyped(java.awt.event.KeyEvent evt) {                                    
    int c = Comentário.getText().length();

    if(c > 16777215){
        BotaoEnviar.setEnabled(false);
        aviso.setText("Faça um comentário menor.");
        aviso.setForeground(Color.red);
    } else{
        aviso.setText(null);
    }

}                                   

private void setIcone() {
    setIconImage(Toolkit.getDefaultToolkit().getImage(Entrada.class.getResource("/Recursos/icone.png")));
}

@Override
public void keyTyped(KeyEvent evt) {
    if(evt.getKeyCode() == KeyEvent.VK_ESCAPE){
        dispose();
    }
}

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Windows".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(Cadastro.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(Cadastro.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(Cadastro.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(Cadastro.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new Pesquisa().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JTextField Altor;
private javax.swing.JButton BotaoEnviar;
private javax.swing.JButton BotaoLimpar;
private javax.swing.JTextArea Comentário;
private javax.swing.JTextField Editora;
private javax.swing.JComboBox Nota;
private javax.swing.JTextField Título;
private javax.swing.JLabel aviso;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration                   

@Override
public void keyPressed(KeyEvent e) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public void keyReleased(KeyEvent e) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

}  

Only this way it’s not working, what I’m doing wrong?

  • Did you come to debug? Pressing the key was actually captured?

2 answers

5


KeyListeners added in frames or panels do not capture keys if the focus is on a field or other component within that form. An alternative would be to add the Systener recursively to all components.

A cleaner solution is to use the KeyboardFocusManager to capture globally the keystrokes pressed in your program.

I did a test by removing the listeners and adding the following code to your class constructor:

KeyboardFocusManager
    .getCurrentKeyboardFocusManager()
    .addKeyEventDispatcher(new KeyEventDispatcher() {
            @Override
            public boolean dispatchKeyEvent(KeyEvent e) {
                System.out.println(e);
                if(e.getID() == e.KEY_RELEASED 
                        && e.getKeyCode() == KeyEvent.VK_ESCAPE){
                    dispose();
                    return true;
                }
                return false;
            }
        });
  • Thank you! It worked for me.

1

The way you are doing (I believe) the event will never be triggered. I had to create something similar a while ago and needed a AbstractAction to define what should occur when the key Esc were pressed.

// Define que nada deve acontecer quando o usuário tentar fechar a janela.
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "FoiPressionadoOESC"
);     

getRootPane().getActionMap().put("FoiPressionadoOESC", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
       fecharJanela();
    }
});

// Como foi definido para "nada" ocorrer quando tentar fechar a janela
// mesmo que o usuário clique no 'x' a janela nãos será fechada. Então
// método serve para a janela ter comportamento padrão. 
this.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent evt){
       fecharJanela();
    }
});

And then when the Esc is pressed or the user clicks 'x' to close the window, the method fecharJanela will be called. In it you can define what should be done when the window is closed, for example:

private void fecharJanela(){
  this.dispose();
}

test code:

import java.awt.event.*;
import javax.swing.*;

public class MeuFrame extends JFrame {

    public MeuFrame(){

        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "EscPressed"
        );

        getRootPane().getActionMap().put("EscPressed", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                fecharJanela();
            }
        });
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent evt){
                fecharJanela();
            }
        });
    }

    private void fecharJanela(){
        this.dispose();
    }

    public static void main(String[] args) {
        new MeuFrame().setVisible(true);
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.