2014-03-26 28 views
1

我有一个小小的Java程序完全可以工作。我想在输入PIN码时使“Enter”键工作。在我写这篇文章的时候,我只能点击按钮来使它工作,所以我想添加这个简单的功能而不用改变所有的代码。在我的Java程序中添加一个简单的Enter键功能

这是我发布的原因,因为我找到了它的几个链接,但没有一个对应我的情况,知道我已经有一个代码工作。我需要适应什么,我发现有:

Allowing the "Enter" key to press the submit button, as opposed to only using MouseClick http://tips4java.wordpress.com/2008/10/10/key-bindings/ http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html http://www.javaprogrammingforums.com/java-swing-tutorials/3171-jbutton-enter-key-keyboard-action.html http://www.rgagnon.com/javadetails/java-0253.html

,他们正在从nohting所有显示的解决方案并不能帮助我,因为我不能用他们做了什么事实在我自己的程序中。

Enter key

正如你所看到的,这是“OK”按钮,我需要点击或按下“Enter”键

这里是我的代码,你有什么建议有回车键工作?

import java.io.*; 
import java.util.*; 
import java.util.concurrent.atomic.AtomicInteger; 
import javax.swing.*; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 
import javax.swing.text.PlainDocument; 
import java.awt.*; 
import java.awt.event.*; 

public class Main extends JFrame { 

    private static final long serialVersionUID = 1L; 

    private JPanel container = new JPanel(); 
    private JPasswordField p1 = new JPasswordField(4); 
    private JLabel label = new JLabel("Enter Pin: "); 
    private JButton b = new JButton("OK"); 


    public Main() { 
     this.setTitle("NEEDS"); 
     this.setSize(300, 500); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setLocationRelativeTo(null); 

     container.setBackground(Color.white); 
     container.setLayout(new BorderLayout()); 
     container.add(p1); 
     JPanel top = new JPanel(); 

     PlainDocument document =(PlainDocument)p1.getDocument(); 

     b.addActionListener(new BoutonListener()); 

     top.add(label); 
     top.add(p1); 
     p1.setEchoChar('*'); 
     top.add(b); 


     document.setDocumentFilter(new DocumentFilter(){ 

      @Override 
      public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { 
       String string =fb.getDocument().getText(0, fb.getDocument().getLength())+text; 

       if(string.length() <= 4) 
       super.replace(fb, offset, length, text, attrs); //To change body of generated methods, choose Tools | Templates. 
      } 
     }); 

     this.setContentPane(top); 
     this.setVisible(true); 
    } 

    class BoutonListener implements ActionListener { 
     private final AtomicInteger nbTry = new AtomicInteger(0); 
     ArrayList<Integer> pins = readPinsData(new File("bdd.txt")); 

     @SuppressWarnings("deprecation") 
     public void actionPerformed(ActionEvent e) { 
      if (nbTry.get() > 2) { 
       JOptionPane.showMessageDialog(null, 
         "Pin blocked due to 3 wrong tries"); 
       return; 
      } 
      final String passEntered=p1.getText().replaceAll("\u00A0", ""); 
      if (passEntered.length() != 4) { 
       JOptionPane.showMessageDialog(null, "Pin must be 4 digits"); 
       return; 
      } 
      //JOptionPane.showMessageDialog(null, "Checking..."); 
      //System.out.println("Checking..."); 
      SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
       @Override 
       protected Void doInBackground() throws Exception { 
        boolean authenticated = false; 
        ImageIcon imgAngry = new ImageIcon("angry.png"); 
        ImageIcon imgHappy = new ImageIcon("happy.png"); 

        if (pins.contains(Integer.parseInt(passEntered))) { 
         JOptionPane.showMessageDialog(null, "Pin correct", "Good Pin", JOptionPane.INFORMATION_MESSAGE, imgHappy); 
         authenticated = true; 
        } 

        if (!authenticated) { 
         JOptionPane.showMessageDialog(null, "Wrong Pin", "Wrong Pin", JOptionPane.INFORMATION_MESSAGE, imgAngry); 
         nbTry.incrementAndGet(); 
        } 
        return null; 
       } 
      }; 
      worker.execute(); 
     } 

    } 

    // Reading bdd.txt file 
    static public ArrayList<Integer> readPinsData(File dataFile) { 
     final ArrayList<Integer> data=new ArrayList<Integer>(); 
     try { 
      BufferedReader reader = new BufferedReader(new FileReader(dataFile)); 
      String line; 
      try { 
       while ((line = reader.readLine()) != null) { 
        try { 
         data.add(Integer.parseInt(line)); 
        } catch (NumberFormatException e) { 
         e.printStackTrace(); 
         System.err.printf("error parsing line '%s'\n", line); 
        } 
       } 
      } finally { 
       reader.close(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.err.println("error:"+e.getMessage()); 
     } 

     return data; 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Main(); 
      } 
     }); 

    } 
} 
+0

如果我理解正确的话,你想实现一个'KeyListener',是这样吗? –

+0

其实这一切都很好。我只是想添加一个函数来使我的键盘上的“Enter”键在我的Button上工作。现在,这个按钮只能点击。 – hacks4life

+0

我应该把这个放在哪里?这正是我的问题,我不知道如何调整我的代码,因为我没有添加从0开始的KeyListener。“ – hacks4life

回答

3

JTextField(其中JPasswordField从继承)提供的只是这个功能ActionListener支持。

p1.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     b.doClick(); // Re-use the Ok buttons ActionListener... 
    } 
}); 

看看How to use text fields更多细节

+0

你建议我创建一个新的actionPerformed方法?或者将此添加到我的代码中? – hacks4life

+0

从技术上讲,你只是重新使用你已经有的'BoutonListener' ... – MadProgrammer

+0

好吧我明白了,但在这种情况下“重用”是什么意思?我需要再次打电话给它? 'b.addActionListener(new BoutonListener());' – hacks4life

1

我觉得这个文档片断应该引导你,在你的类添加以下代码:

@Override 
public void actionPerformed(ActionEvent e) { 
    b.doClick(); 
} 
+0

我的问题是,我试图调整一些这样的例子到我的代码,我没有设法使它的工作。我需要确切地看到如何将其添加到我的已制作的代码中。 – hacks4life

+1

'KeyListener'很差,实际上,这是一个糟糕的选择。 'JTextField'有一个'ActionListener',它以独立于平台的方式为此功能而设计。您无法保证处理关键事件的顺序,并且在某些平台上,关键事件可能会在您之前消耗,这意味着它可能永远不会传达给您的听众。同样,你永远不应该依赖神奇的数字。 'keyCode'可能在平台之间改变 – MadProgrammer

+2

1)'KeyListener'通常是Swing功能的错误级别。 2)'if(e.getKeyCode()== 10){'不要使用幻数。 3)密码字段支持['ActionListener'](http://docs.oracle.com/javase/8/docs/api/javax/swing/JTextField.html#addActionListener-java.awt.event.ActionListener-) .. –

2
JTextField yourtexfield=new JTextField(8); 

yourterxtfield.addActionListener(new ActionListener(){ 

     public void actionPerformed(ActionEvent e){ 
      // your code 
     } 
}); 
+0

我不明白你的解决方案...你有什么建议? – hacks4life

1

编辑:哦,对不起。没有意识到你正在使用Swing/AWT。这是SWT功能,因此不会帮助解决您的问题。

我使用TraverseListener来实现该行为。你可以试试这个:

 p1.addTraverseListener(new TraverseListener() { 
     @Override 
     public void keyTraversed(TraverseEvent e) { 
      switch (e.detail) { 
       case SWT.TRAVERSE_RETURN: 
       doWhateverYourButtonClickDoesHere(); 
       break; 
      } 
     } 
    }); 
-1

充实my comment to @Mad's answer

[调用button.doClick()]是不是最佳的解决方案,因为它引入了一些看法之间的不必要的耦合相反,使用一个行动并将其设置为两个文本框和按钮

优点:

  • (正如已经指出的):视图
  • 单个位置之间没有耦合到执行登录逻辑
  • 已启用的概念,因此可以被禁用 - 并与它势必所有视图。在锁定的登录

原料(以有点太多的责任,进一步分离强烈建议)的代码片段,接管

  • 抢有效引脚
  • 注册的DocumentFilter
  • 验证/锁登录

行动:

public static class LoginAction extends AbstractAction { 
    private final AtomicInteger nbTry = new AtomicInteger(0); 
    private ArrayList<Integer> pins = readPinsData(new File("bdd.txt")); 
    private Document doc; 

    public LoginAction(String login, AbstractDocument doc) { 
     super(login); 
     this.doc = doc; 
     doc.setDocumentFilter(new DocumentFilter(){ 

      @Override 
      public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { 
       String string =fb.getDocument().getText(0, fb.getDocument().getLength())+text; 
       if(string.length() <= 4) 
        super.replace(fb, offset, length, text, attrs); 
      } 
     }); 

    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (nbTry.get() > 2) { 
      JOptionPane.showMessageDialog(null, 
        "Pin blocked due to 3 wrong tries"); 
      setEnabled(false); 
      return; 
     } 
     String passEntered = null; 
     try { 
      passEntered = doc.getText(0, doc.getLength()).replaceAll("\u00A0", ""); 
     } catch (BadLocationException e1) { 
      e1.printStackTrace(); 
     } 
     if (passEntered.length() != 4) { 
      JOptionPane.showMessageDialog(null, "Pin must be 4 digits"); 
      return; 
     } 
     boolean authenticated = false; 
     ImageIcon imgAngry = new ImageIcon("angry.png"); 
     ImageIcon imgHappy = new ImageIcon("happy.png"); 

     if (pins.contains(Integer.parseInt(passEntered))) { 
      JOptionPane.showMessageDialog(null, "Pin correct", "Good Pin", JOptionPane.INFORMATION_MESSAGE, imgHappy); 
      authenticated = true; 
     } 

     if (!authenticated) { 
      JOptionPane.showMessageDialog(null, "Wrong Pin", "Wrong Pin", JOptionPane.INFORMATION_MESSAGE, imgAngry); 
      nbTry.incrementAndGet(); 
     } 

    } 

} 

它的使用:

PlainDocument document =(PlainDocument)passwordField.getDocument(); 
LoginAction action = new LoginAction("OK", document); 
passwordField.setAction(action); 
loginButton.setAction(action); 
相关问题