簡體   English   中英

如何使用 keyTyped(event e) 一次檢查多個鍵

[英]How to check for multiple keys at once using keyTyped(event e)

我有以下代碼:

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.
}

現在我希望它在每次按下打印字符(az、1-9、0、*、+、# 等特殊符號)的鍵時運行 keyTyped 事件。 (另外,我想在按 Enter、Backspace 或 Delete 后檢查 JTextArea 是否為空)。 問題是,做一個常規的 if-else 或 switch-case-statement 是荒謬的。 想象一下做 26+10+dontKnowHowMuch 條件來檢查每個這樣的鍵。 有沒有辦法讓它變短,所以我不需要那樣拉伸它?


更新:我將以下代碼寫入 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
            
        }
    });

而且無論我在 JTextArea 中鍵入什么內容,也無論 KeyListener 是用於 newTask 還是用於 newTask_field,都不會發生任何事情。 標志出現在 JTextArea 中,但 KeyListener 什么也不做。 任何想法為什么?

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() ),它返回按下的鍵的字符。

所以你可以使用:

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

至於 Enter、Backspace 和 Delete,您只需檢查是否按下了這些鍵並執行您的操作。

因此,您的 keyTyped-Body 可能/應該如下所示:

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

希望這能解決您的問題。


編輯:

在我自己測試了一些代碼后,我發現了問題,你將監聽器添加到 newTask。 在我將偵聽器添加到 newTask 的 newTask_field 后,它工作正常。

在 scope 之外:也許為 main-Method 創建一個單獨的 Main-class 並將 MyList 作為 class 沒有 main-Method。 然后在構造函數中創建所有對象並從那里繼續。

從您提供的信息來看,您似乎需要 PropertyChangeListener() 之類的東西。

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

更新:

或者,為了操縱Swing JTextField中的文本屬性更改,您需要使用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);
                
            }
        });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM