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);
}
});