如何使用 Action Listener 和 Action Event 让 JButtons 在 JTextField 中打印整数?

Posted

技术标签:

【中文标题】如何使用 Action Listener 和 Action Event 让 JButtons 在 JTextField 中打印整数?【英文标题】:How to get JButtons to print integers in a JTextField by using Action Listener and Action Event? 【发布时间】:2015-07-15 02:30:37 【问题描述】:

我正在尝试创建和假设 ATM GUI 界面以通过键盘输入几个数字。在用户单击任何按钮后,我无法让程序显示数字。为了时间,我只创建了一个按钮:

public JButton jbtOne = new JButton(STANDARD_BTN_TEXTS[0][0]);

所以如果用户点击“jbtOne”说 4 次。 JTextField 应该显示 1111。我的问题是按钮对代码行没有响应:

addActionListener(listener)

如何让 JButtons 在 JTextField 中打印整数?我之前已经让它工作了,但是在用这行代码添加了一个更用户友好的外观之后,它就无法再次工作了:

 private static final String[][] STANDARD_BTN_TEXTS = 

    "1", "2", "3",
    "4", "5", "6",
    "7", "8", "9",
     "0" 

有人能指出我正确的方向吗?任何帮助将不胜感激!

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JPasswordField;

public class TerminalATM extends JFrame

private JPanel panel;
public final JPasswordField passwordField = new JPasswordField(2);
private static final String[][] STANDARD_BTN_TEXTS = 

    "1", "2", "3",
    "4", "5", "6",
    "7", "8", "9",
     "0" 
;
private static final int GAP = 5;
private static final Font BTN_FONT = new Font(Font.DIALOG, Font.BOLD, 20);
public JButton jbtOne = new JButton(STANDARD_BTN_TEXTS[0][0]);
 private JTextField jtfNumber1 = new JTextField(8);//Define Number Field

public TerminalATM()
       
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null); 

    JPanel standardPanel = createBtnPanel(STANDARD_BTN_TEXTS, "KeyPad");
    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new GridLayout(0, 1));
    buttonPanel.add(jtfNumber1, BorderLayout.NORTH);
    buttonPanel.add(standardPanel, BorderLayout.SOUTH);



    BtnListener listener = new BtnListener();
    jbtOne.addActionListener(listener);

    TextFieldHandler handler = new TextFieldHandler();
    passwordField.addActionListener(handler);

    add(buttonPanel, BorderLayout.LINE_START);
    setSize(450, 500);
    setVisible(true);


//Create Unique Rows of Buttons
private JPanel createBtnPanel(String[][] texts, String title) 
    JPanel btnPanel = new JPanel();
    int rows = texts.length;
    int cols = texts[0].length;
    btnPanel.setLayout(new GridLayout(rows, cols, GAP, GAP));
    for (int row = 0; row < texts.length; row++) 
        for (int col = 0; col < texts[row].length; col++) 
            JButton btn = new JButton(texts[row][col]);
            btn.setFont(BTN_FONT);
            btnPanel.add(btn);
        
    
    btnPanel.setBorder(BorderFactory.createTitledBorder(title));
    return btnPanel;
  


  private class TextFieldHandler implements ActionListener
 

  @Override
  public void actionPerformed(ActionEvent event)
  
  String string = "";

 if(event.getSource()==passwordField)
 string = String.format("textField1: %s", event.getActionCommand());
 
  

/**** Create Button Listener and Action Listener ****/
 class BtnListener implements ActionListener 

    @Override
 public void actionPerformed(ActionEvent e)

      /* This is where we would set each button to the action event */
      /* Only Button one for brevity */
   int int1=0;
 if(e.getSource().equals(jbtOne))

     int1 = 1;
  passwordField.setText(String.valueOf(int1));

  
 
 


public static void main(String[] args)

    SwingUtilities.invokeLater(new Runnable()
    
    public void run()
    
    new TerminalATM();
    
    );
   
 //EndTerminalATM

【问题讨论】:

【参考方案1】:

在我看来,您没有将jbtOne 添加到可见面板。您的 createBtnPanel 方法会创建自己的按钮并将它们添加到面板中,而无需任何操作侦听器。

尝试更改createBtnPanel的内部循环的以下行:

for (int row = 0; row < texts.length; row++) 
    for (int col = 0; col < texts[row].length; col++) 
        final String text = texts[row][col];
        final JButton btn = new JButton(text);
        btn.addActionListener(new ActionListener() 
            public void actionPerformed(ActionEvent ev) 
                passwordField.setText(text);
            
        );
        btn.setFont(BTN_FONT);
        btnPanel.add(btn);
    

如果您不明白它的作用或有任何问题,请告诉我。

如果您使用的是 Java 8,此代码也可以大大简化,但我假设您不会让我的回答直截了当。

【讨论】:

感谢 Sprinter 的帮助!是的,我在理解目的时遇到了麻烦,当我实现时,我收到一个错误:局部变量文本是从内部类中访问的;需要声明为final。我做了,但没有影响。你能进一步澄清/解释你的建议吗?(使用 dr.java 和编译器:JDK 7.0) 最简单的解决方法是将文本复制到本地最终变量。我已经更新了答案以反映这一点。【参考方案2】:

在下面的代码中,我让按钮侦听器响应并输出单击按钮的文本以显示在文本字段中。 所有更改都以 /**** 开头记录,以解释我所做的。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package logging;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class TerminalATM extends JFrame

    private JPanel panel;
    public final JPasswordField passwordField = new JPasswordField(2);
    private static final String[][] STANDARD_BTN_TEXTS =
        
        "1", "2", "3",
        "4", "5", "6",
        "7", "8", "9",
         "0" 
        ;
    private static final int GAP = 5;
    private static final Font BTN_FONT = new Font(Font.DIALOG, Font.BOLD, 20);
    /**** what is the purpose of this JButton ? */
    public JButton jbtOne = new JButton(STANDARD_BTN_TEXTS[0][0]);
    private JTextField jtfNumber1 = new JTextField(8);//Define Number Field

    public TerminalATM()
    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel standardPanel = createBtnPanel(STANDARD_BTN_TEXTS, "KeyPad");
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(0, 1));
        buttonPanel.add(jtfNumber1, BorderLayout.NORTH);
        buttonPanel.add(standardPanel, BorderLayout.SOUTH);

        /**** The action listener should go on the button which is pressed
         see createBtnPanel  */
//      BtnListener listener = new BtnListener();
//      jbtOne.addActionListener(listener);

        /**** what is the purpose of this JPasswordField ?
         it is not being added to any JPanel */
        TextFieldHandler handler = new TextFieldHandler();
        passwordField.addActionListener(handler);

        add(buttonPanel, BorderLayout.LINE_START);
        setSize(450, 500);
        setVisible(true);
    

    //Create Unique Rows of Buttons
    private JPanel createBtnPanel(String[][] texts, String title) 
        JPanel btnPanel = new JPanel();
        int rows = texts.length;
        int cols = texts[0].length;
        btnPanel.setLayout(new GridLayout(rows, cols, GAP, GAP));

        /**** create the listener */
        BtnListener listener = new BtnListener();
        for (String[] text : texts) 
            for (String element : text) 
                JButton btn = new JButton(element);
                btn.setFont(BTN_FONT);

                /**** add the listener to each button*/
                btn.addActionListener(listener);
                btnPanel.add(btn);
            
        
        btnPanel.setBorder(BorderFactory.createTitledBorder(title));
        return btnPanel;
    


    private class TextFieldHandler implements ActionListener
    

        @Override
        public void actionPerformed(ActionEvent event)
        
            String string = "";

            if(event.getSource()==passwordField) 
                string = String.format("textField1: %s", event.getActionCommand());
            
        
    

    /**** Create Button Listener and Action Listener ****/
    class BtnListener implements ActionListener
    
        @Override
        public void actionPerformed(ActionEvent e)
        

            /* This is where we would set each button to the action event */
            /* Only Button one for brevity */

            /**** what is the purpose of it ?   int int1=0; */

            /****  the event is generated by the button created in
             createBtnPanel so e.getSource()  can not be equal to
             jbtOne. It should be an instance of JButton  */

            if(e.getSource() instanceof JButton)
            
                /**** get the JButton clicked */
                JButton button = (JButton) e.getSource() ;
                /**** display its text on the text field */
                jtfNumber1.setText(button.getText());
            
        
    


    public static void main(String[] args)
    
        SwingUtilities.invokeLater(new Runnable()
        
            @Override
            public void run()
            
                /**** new MultiplePanels(); is un defined */
                new TerminalATM();
            
        );
    

//EndTerminalATM

我需要更好地了解您希望使用密码字段和操作侦听器实现什么功能,因此如果需要,我可以尝试进一步帮助您。 (0:

【讨论】:

【参考方案3】:

您的听众正在使用 passwordField,但您似乎已在面板中添加了一个文本字段,请使用 passwordField 或 jtfNumber1。

【讨论】:

以上是关于如何使用 Action Listener 和 Action Event 让 JButtons 在 JTextField 中打印整数?的主要内容,如果未能解决你的问题,请参考以下文章

JSF:-DataType 和 Action Listener 的问题

Paho C ++异步客户端回调vs action_listener vs connected_handler

Flutter 触摸事件监听 Listener 手势识别示例

如何从 MethodInfo 创建 Action 委托?

listener 监听 tomcat 容器的初始化和销毁

如何用Java实现短信自动发送功能