Home > Back-end >  How to check for multiple keys at once using keyTyped(event e)
How to check for multiple keys at once using keyTyped(event e)

Time:09-21

I have the following code:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import javax.swing.event.*;

@SuppressWarnings("serial")
public class MyList extends JFrame implements ActionListener, ListSelectionListener, KeyListener
{
static MyList mylist = new MyList();

public static void main(String[] args)
{
    // TODO Auto-generated method stub
    
    JFrame frame = new JFrame();
    frame.setSize(600,800);
    frame.setDefaultCloseOperation(3);
    
    JPanel panel = new JPanel();
    
    JLabel title = new JLabel("<html><body><h1>To-Do-List</h1></body></html>");
    title.setPreferredSize(new Dimension(600, 80));
    title.setHorizontalAlignment(JLabel.CENTER);
    /*title.setOpaque(true);
    title.setBackground(Color.cyan);*/
    
    /*JTextField newTask = new JTextField();
    newTask.setHorizontalAlignment(JTextField.CENTER);
    newTask.setPreferredSize(new Dimension(400,40));*/
    JTextArea newTask_field = new JTextArea(3,1);
    newTask_field.setPreferredSize(new Dimension(400,80));
    newTask_field.setLineWrap(true);
    newTask_field.setWrapStyleWord(true);
    
    JScrollPane newTask = new JScrollPane(newTask_field);
    newTask.setPreferredSize(new Dimension(400,80));
    
    JButton confirm = new JButton("Add");
    confirm.setHorizontalAlignment(JButton.CENTER);
    confirm.setEnabled(false);
    
    DefaultListModel<String> listModel = new DefaultListModel<>();
    //listModel.addElement("");
    
    JList<String> done = new JList<String>(listModel);
    done.setPreferredSize(new Dimension(200, 400));
    
    
    DefaultListModel<String> listModel2 = new DefaultListModel<>();
    
    JList<String> notDoneYet = new JList<String>(listModel2);
    notDoneYet.setPreferredSize(new Dimension(200, 400));
    
    panel.add(title);
    //panel.add(newTask);
    panel.add(newTask);
    panel.add(mylist.createEmptySpace(new JLabel(), 600, 40));
    panel.add(confirm);
    panel.add(mylist.createEmptySpace(new JLabel(), 600, 0));
    panel.add(done);
    panel.add(mylist.createEmptySpace(new JLabel(), 100, 400));
    panel.add(notDoneYet);
    frame.add(panel);
    frame.setVisible(true);
    
    
    //-------------------------------//
    
    newTask.setFocusable(true);
    newTask_field.setFocusable(true);
    
    if(newTask_field.getText().equals(""))
    {
        //unused if-statement
    }
    newTask.addKeyListener(new KeyListener()
    {
        
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
            if(e.getKeyCode()==KeyEvent.VK_A)
            {
                
            }
            
        }
        
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            
        }
    });
    
    
}

//Method createEmptySpace(JLabel(), int, int) which works.
}

Now I want it to run the keyTyped event everytime I press a key which prints a character (a-z, 1-9, 0, special signs like *, , # and so on). (Also, I would like to check if the JTextArea is empty after I pressed Enter, Backspace or Delete). The problem is, doing a regular if-else or switch-case-statement is ridiculous. Imagine doing 26 10 dontKnowHowMuch conditions to check every single key like this. Is there a way to make it short so I don't need to stretch it like that?


Update: I wrote the following code into the KeyListener:

newTask_field.addKeyListener(new KeyListener()
    {
        
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
            if(e.getKeyCode()==KeyEvent.VK_A)
            {
                confirm.setEnabled(true);
                newTask_field.setText(newTask_field.getText()   e.getKeyCode());
            }
            if(e.getKeyCode()==KeyEvent.VK_ALPHANUMERIC)
            {
                System.out.println("Alphanumeric sign");
                confirm.setEnabled(true);
                newTask_field.setText(newTask_field.getText()   e.getKeyChar());
            }
            if(e.getKeyChar()==KeyEvent.VK_UNDEFINED)
            {
                System.out.println("Undefined");
            }
            
        }
        
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
            
            
            
            if(e.getKeyCode()==KeyEvent.VK_BACK_SPACE || e.getKeyCode()==KeyEvent.VK_DELETE
                    || e.getKeyCode()==KeyEvent.VK_ENTER || e.getKeyCode()==KeyEvent.VK_SPACE
                    || e.getKeyCode()==KeyEvent.VK_TAB || e.getKeyCode()==KeyEvent.VK_CIRCUMFLEX
                    || e.getKeyCode()==KeyEvent.VK_DEAD_ACUTE || e.getKeyCode()==KeyEvent.VK_DEAD_GRAVE)
            {
                if (newTask_field.getText().isBlank())
                {
                    confirm.setEnabled(false);
                }
            }
            
            if(e.getKeyCode()==KeyEvent.VK_UNDEFINED)
            {
                System.out.println("Undefined");
            }
        }
        
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            
        }
    });

And no matter what I typed in the JTextArea and no matter whether the KeyListener is for newTask or for newTask_field, nothing ever happens. The signs appear in the JTextArea, but the KeyListener does nothing. Any ideas why?

CodePudding user response:

Quickly taking a look at https://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html reveals the 'getKeyChar()'-Method(https://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html#getKeyChar()), which returns the character of the pressed key.

So you can then use:

newTask_field.setText(newTas_field.getText()   e.getKeyChar());

As for Enter, Backspace and Delete, there you just check, if you pressed those and do your actions.

So therefore your keyTyped-Body could/should look like this:

if ((e.getKeyCode() == KeyEvent.ENTER || e.getKeyCode() == KeyEvent.BACK_SPACE || e.getKeyCode() == KeyEvent.DELETE) && newTask_field.getText().Equals("")) {
    //do your stuff
    return;
}
newTask_field.setText(newTas_field.getText()   e.getKeyChar());

Hope this solves your problem.


Edit:

After testing the code myself a bit i found the problem, that you add the listener to newTask. After i added the listener to newTask_field instad of newTask, it worked fine.

Out of scope: Maybe create a separate Main-class for the main-Method and have the MyList as a class without a main-Method. Then you create all the objects in the constructor and move on from there.

CodePudding user response:

From the info you've provided, it seems that you need something like the PropertyChangeListener().

newTask_field.addPropertyChangeListener(new PropertyChangeListener() {
            
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if(evt.getNewValue().equals("")) {
                
                    confirm.setEnabled(false);
                }else {
                    confirm.setEnabled(true);
                }
            }
        });

UPDATE:

Or, turns out in order to manipulate the text property changes in Swing JTextField you need to use addDocumentListener()

newTask_field.getDocument().addDocumentListener(new DocumentListener() {
            
            @Override
            public void removeUpdate(DocumentEvent e) {
                if(txt.getText().equals("")) {
                    confirm.setEnabled(false);
                }
                
            }
            
            @Override
            public void insertUpdate(DocumentEvent e) {
                confirm.setEnabled(true);
                
            }
            
            @Override
            public void changedUpdate(DocumentEvent e) {
                confirm.setEnabled(true);
                
            }
        });
  • Related