为什么不使用Enter键而不是点击所有的动作按钮功能?

为什么不使用Enter键而不是点击所有的动作按钮功能?

问题描述:

我的操作按钮会读取JTextField值,并仅使用包含在原始值中的数字更新相同的字段。它还会自动将数字复制到剪贴板并使JLabel可见,让用户知道它被复制。只要用户再次输入文本字段,该标签就会再次隐藏。为什么不使用Enter键而不是点击所有的动作按钮功能?

示例:用户输入“abc123cde456”并单击操作按钮。输出是“123456”。显示一个标签,告诉该值已被复制。

我已经使此按钮的默认设置为getRootPane()。setDefaultButton(button)因此用户可以使用Enter键来触发它。问题是,当使用键而不是鼠标点击时,输出和复制到剪贴板工作,但JLabel不可见。

我注意到Enter键在按下键前将焦点从JTextField中设置为焦点时可以正常工作,但在布局中唯一的方法是将鼠标单击在按钮顶部并将其“拖动”外面,所以重点转到按钮而不是JTextField中,像这样:下面

passing focus to button before hitting Enter key

码 - 通过,我正在NetBeans IDE的方式:

JFrame类

import java.awt.Toolkit; 
import java.awt.datatransfer.Clipboard; 
import java.awt.datatransfer.StringSelection; 

public class FrameZ extends javax.swing.JFrame { 

    public FrameZ() { 
     initComponents(); 
     labelCopied.setVisible(false); 
     inputTxt.addActionListener(actionButton.getActionListeners()[0]); 
     getRootPane().setDefaultButton(actionButton); 
    } 

    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code">       
    private void initComponents() { 

     inputTxt = new javax.swing.JTextField(); 
     actionButton = new javax.swing.JButton(); 
     labelCopied = new javax.swing.JLabel(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     inputTxt.addKeyListener(new java.awt.event.KeyAdapter() { 
      public void keyTyped(java.awt.event.KeyEvent evt) { 
       inputTxtKeyTyped(evt); 
      } 
     }); 

     actionButton.setText("Only numbers"); 
     actionButton.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       actionButtonActionPerformed(evt); 
      } 
     }); 

     labelCopied.setText("Copied!"); 

     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(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
         .addGap(0, 0, Short.MAX_VALUE) 
         .addComponent(labelCopied) 
         .addGap(72, 72, 72)) 
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
         .addComponent(inputTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 127, javax.swing.GroupLayout.PREFERRED_SIZE) 
         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) 
         .addComponent(actionButton) 
         .addContainerGap()))) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 
        .addComponent(actionButton) 
        .addComponent(inputTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 
       .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
       .addComponent(labelCopied) 
       .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 
     ); 

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

    private void actionButtonActionPerformed(java.awt.event.ActionEvent evt) {            

     String inputValue = inputTxt.getText(); 
     StringBuilder digitsOnly = new StringBuilder(); 

     for (int i = 0; i < inputValue.length(); i++) { 
      char c = inputValue.charAt(i); 
      if (Character.isDigit(c)) { 
       digitsOnly.append(c); 
      } 
     } 

     inputTxt.setText(digitsOnly.toString()); 

     //copying to clipboard: 
     StringSelection strSelect = new StringSelection(inputTxt.getText()); 
     Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); 
     clpbrd.setContents(strSelect, null); 

     labelCopied.setVisible(true); 
    }            

    private void inputTxtKeyTyped(java.awt.event.KeyEvent evt) {         
      labelCopied.setVisible(false); 
    }         

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new FrameZ().setVisible(true); 
      } 
     }); 
    } 

    // Variables declaration - do not modify      
    private javax.swing.JButton actionButton; 
    private javax.swing.JTextField inputTxt; 
    private javax.swing.JLabel labelCopied; 
    } 

主要类

public class Main { 
    public static void main(String args[]){ 
     FrameZ frm = new FrameZ(); 

     frm.setVisible(true); 
     frm.setResizable(false); 
     frm.setLocationRelativeTo(null); 
    } 
} 
+5

发布演示问题的[mcve]。 – camickr

+0

操作系统或swing的* enter-key *在操作系统或操作系统默认情况下**不会**作为*点击* **。这是一个必须在程序中定义的操作。只需研究诸如“*摇摆按钮输入键*”。您将找到显示如何为Enter键定义默认操作的结果。例如,您可以定义应用程序的默认按钮。如果你的应用程序有焦点,并且你按下回车键,那么它会触发该按钮等等。 – Zabuza

+1

如果以@camickr的身份请求意味着您需要发布所有代码,请这样做。我无法运行您的发布代码。 – Charles

为了解决问题,你需要:

  1. 使用调试器单步执行代码
  2. 添加的System.out.println(...)语句您的代码

以上任何一种都可以帮助您了解逻辑流程,以了解它是否符合您的期望。

我不使用IDE,所以我做了以下修改添加一些调试代码:

private void actionButtonActionPerformed(java.awt.event.ActionEvent evt) { 
System.out.println("action"); 

private void inputTxtKeyTyped(java.awt.event.KeyEvent evt) { 
    System.out.println("hide"); 

如果你做这些改变和类型数据在文本字段并使用回车键你会看到如下输出:

hide 
hide 
hide 
hide 
action 
hide 

为什么会发生这种情况?那么,这样看来,回车键生成KeyTyped事件,该事件之后的修复此ActionEvent

一种方式处理,是包装,使标签在SwingUtilities.invokeLater(...)可见的逻辑。这将导致代码被添加到事件队列的末尾,以便在Enter键生成事件后执行代码:

//labelCopied.setVisible(true); 
    SwingUtilities.invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      labelCopied.setVisible(true); 
     } 
    }); 
+0

这非常有道理。现在正在工作。谢谢! – elxapinhon