【问题标题】:Java multiple Button actionJava 多按钮动作
【发布时间】:2011-12-27 23:33:48
【问题描述】:

我需要开发一个带有 GUI 的 Java 应用程序,它代表一台 ATM 机。为此,我必须从“键盘”(9 个按钮)读取帐号和 PIN。我必须读取每个按下按钮的每个动作(动作侦听器返回按钮的值),并将他的数字连接到一个字符串,当按下按钮“ok”时它应该返回 int (Integer.parseInt())。我的问题是如何“等待\停止\冻结”我的程序,直到引入数字并按下“确定”?

如果这个问题有点令人困惑,我很抱歉

感谢您的帮助;)

P.S 我为 ATM 机的每一部分都有一个课程。 EG:键盘、屏幕、ATM..等

P.S.S 如果你想看一些代码,请告诉;)

【问题讨论】:

  • 你需要使用事件处理程序(监听器)而不是循环。
  • stackoverflow 变成 homeworkoverflow 了吗?
  • 谢谢大家。你们都帮了我很多,谢谢;)。我终于发现了我的大问题,那就是线程。我在一个线程中制作了所有程序,我知道我将它分成两部分,一个创建窗口,另一个运行程序。非常感谢;)

标签: java swing user-interface jbutton


【解决方案1】:

包含小键盘组件和“确定”按钮的组件应该将自己注册为ActionListener。为了区分源组件,请使用EventObjectgetSource() 方法。确定是哪个组件生成了事件后,将数字添加到集合中,或验证输入的 PIN。


以下代码 sn-p 尝试验证输入的 PIN 码的长度:

示例 -

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.text.MaskFormatter;

final class ATMDemo extends JFrame implements ActionListener{
    private static final long serialVersionUID = -8099290319139531183L;
    private final JFormattedTextField textField;
    private final JPanel layerOne;
    private final JPanel layerTwo;
    private final JPanel layerThree;
    private final JPanel layerFour;
    private final JPanel layerFive;
    private final JPanel layerSix;
    private final JButton one;
    private final JButton two;
    private final JButton three;
    private final JButton four;
    private final JButton five;
    private final JButton six;
    private final JButton seven;
    private final JButton eight;
    private final JButton nine;
    private final JButton zero;
    private final JButton okButton;
    private final JButton clearButton;

    private ATMDemo() throws ParseException{
        super("ATM Demo");
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        layerOne = new JPanel();
        layerTwo = new JPanel();
        layerThree = new JPanel();
        layerFour = new JPanel();
        layerFive = new JPanel();
        layerSix = new JPanel();

        // Add layer one
        textField = new JFormattedTextField(new MaskFormatter("*********"));
        textField.setEditable(false);
        textField.setColumns(7);
        layerOne.add(textField);

        // Add layer two
        one = new JButton(String.valueOf(1));
        two = new JButton(String.valueOf(2));
        three = new JButton(String.valueOf(3));
        layerTwo.add(one);
        layerTwo.add(two);
        layerTwo.add(three);

        // Add layer three
        four = new JButton(String.valueOf(4));
        five = new JButton(String.valueOf(5));
        six = new JButton(String.valueOf(6));
        layerThree.add(four);
        layerThree.add(five);
        layerThree.add(six);

        // Add layer four
        seven = new JButton(String.valueOf(7));
        eight = new JButton(String.valueOf(8));
        nine = new JButton(String.valueOf(9));
        layerFour.add(seven);
        layerFour.add(eight);
        layerFour.add(nine);

        // Add layer five
        zero = new JButton(String.valueOf(0));
        layerFive.add(zero);

        // Add layer six
        okButton = new JButton("OK");
        clearButton = new JButton("Clear");
        layerSix.add(okButton);
        layerSix.add(clearButton);
    }

    @Override
    public final void actionPerformed(final ActionEvent e) {
        final JButton source = (JButton)e.getSource();
        if(source.equals(okButton)){
            if(textField.getValue() != null && textField.getValue().toString().length() != 9){
                JOptionPane.showMessageDialog(this, "Invalid PIN length - must be 9 digits long.", "Error", JOptionPane.ERROR_MESSAGE);
            }
            else{
                JOptionPane.showMessageDialog(this, "Valid PIN length.", "Valid", JOptionPane.INFORMATION_MESSAGE);
            }
            clearButton.doClick();
        }
        else if(source.equals(clearButton)){
            textField.setValue(null);
        }
        else{
            final StringBuilder sb = new StringBuilder();
            if(textField.getValue() != null){
                for(char c: textField.getValue().toString().toCharArray()){
                    sb.append(c);
                }
            }

            if(sb.length() != 9){
                sb.append(source.getText());
                textField.setValue(sb);
            }
        }
    }

    static final ATMDemo newInstance() throws ParseException{
        final ATMDemo demo = new ATMDemo();
        demo.one.addActionListener(demo);
        demo.two.addActionListener(demo);
        demo.three.addActionListener(demo);
        demo.four.addActionListener(demo);
        demo.five.addActionListener(demo);
        demo.six.addActionListener(demo);
        demo.seven.addActionListener(demo);
        demo.eight.addActionListener(demo);
        demo.nine.addActionListener(demo);
        demo.zero.addActionListener(demo);
        demo.okButton.addActionListener(demo);
        demo.clearButton.addActionListener(demo);
        demo.add(demo.layerOne);
        demo.add(demo.layerTwo);
        demo.add(demo.layerThree);
        demo.add(demo.layerFour);
        demo.add(demo.layerFive);
        demo.add(demo.layerSix);
        demo.setSize(225, 250);
        demo.setLocationRelativeTo(null);
        return demo;
    }

    public static final void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                try {
                    ATMDemo.newInstance().setVisible(true);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

a) PIN 长度无效

b) 有效的 PIN 长度

【讨论】:

  • 我已经这样做了。我的问题更难,(至少我认为是:P)。我需要在某一时刻“冻结”我的程序,以便用户可以介绍所有需要的数据。我需要在 GUI 中执行 Scanner 在 CLI 中执行的操作。
  • @user1118437,请参阅编辑。同样“冻结”程序,尤其是用户界面用户友好*。
【解决方案2】:
  1. JFrame
  2. 创建一个名为 pinString 的实例变量。将其初始化为 ""。
  3. 制作一个“JPanel”。
  4. 为您的按钮定义一个ActionListener 类。在构造函数中,放置按钮 A​​ctionListener 在其按钮被点击时将添加的文本。
  5. 制作 9 个按钮。将ActionListener 添加到每个。对于JButton 1,使 ActionListener 添加“1”。对于JButton 2,使其添加“2”。等等……
  6. 将按钮添加到 JPanel。
  7. 制作另一个 JButton,即“确定”按钮。
  8. 让其动作侦听器Integer.parseInt() pinString 并使用真正的 PIN 检查解析的值,如果它们匹配或不匹配,则执行您想要执行的任何操作。
  9. 将按钮添加到面板。
  10. 将 Frame 的内容窗格设置为面板。
  11. 显示/包装框架。它应该可以工作。

【讨论】:

  • 我已经这样做了。我的问题更难,(至少我认为是:P)。我需要在某一时刻“冻结”我的程序,以便用户可以介绍所有需要的数据。我需要在 GUI 中执行 Scanner 在 CLI 中执行的操作。
  • @user1118437:同样,您不需要“冻结”您的程序。你需要响应它的状态。请相信我和我们其他人,因为我们已经在比你们更“复杂”的程序中多次这样做了。
【解决方案3】:

查看其他代码会有所帮助; java计算器教程很多。原则上,您可以禁用 OK 按钮 (setEnabled(false)),并将 4 个键添加到全局字符串:setEnabled(pinCode.length() == 4)

【讨论】:

  • 我该如何解释。在那种程序中,“程序完成”,然后我可以“随意使用按钮,但在这种情况下我不能这样做,因为 ATM 必须首先从用户那里获取一个 int(来自 Keypad 类) 然后在验证 nrAcount 之后,它必须从同一类接收另一个 int,但这次是 pin。这就是为什么我的想法是冻结程序,直到用户没有引入所有数字~
  • 不能按顺序询问 1、2、3、4 密码然后继续。一个人可能只禁用所有按钮,但数字按钮除外。然后在输入4位数字后,启用其他按钮,并改变状态处理下一步。这是与模态序列相反的事件驱动方法。
【解决方案4】:

也许你正在寻找一个模态对话框之类的东西。例如

String pinString = JOptionPane.showInputDialog(parent, "PIN");

这将“冻结”主 GUI 直到被解散。

检查返回值。如果是null,则用户取消了对话。

【讨论】:

    【解决方案5】:

    您不想“冻结”您的程序。相反,您希望对其进行编码,以便响应按下 OK 按钮的侦听器仅在先前按下数字按钮时才会执行其操作。这将要求您为类提供一个变量,该变量保存最后一次按下 xxx 按钮的结果(数组或列表可以为此工作,甚至是一个简单的字符串),然后在您的 ok 按钮的侦听器中,有一个 if 块来检查这个变量,如果OK,就发挥它的魔力。

    例如,您可以将 String 称为 pinInput 并使其 = "" 或空字符串(或者更好的是 StringBuilder ——但这对于您的简单程序来说并非完全必要)。在每个数字按钮侦听器中,您将表示按下的数字的字符串连接到 pinInput 字符串上。在 OK 按钮的侦听器中,您检查 pinInput 的长度是否大于所需的最小字符长度,如果是,则从字符串中取出最后 x 个字符并测试它们是否与 PIN 匹配。

    编辑:
    你说:

    ATM 类将是程序的“主”,它将调用 Keypad 类的方法 readInt()。我应该在这里得到用户介绍的号码。

    如果需要,您可以允许主类向任何其他类添加侦听器,以便在按下按钮时得到通知。

    无论您怎么看,您都需要使用侦听器,以便您的程序响应事件(“事件驱动”)。这就是 Java Swing GUI 的工作方式。

    编辑 2
    例如,在下面的代码中,JFrame 拥有一个 JPanel,上面有 JButton,并且 JFrame 仅在 JPanel 上的按钮按特定顺序按下时才会响应——A,然后 B,然后 OK:

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.*;
    
    public class AnExample {
       private static void createAndShowGui() {
          AnExample mainPanel = new AnExample();
    
          JFrame frame = new AnExMain();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    
    class AnExMain extends JFrame {
       private JTextField field = new JTextField(
             "Press A, then B, then OK, in that order", 20);
       private Control control = new Control(this);
    
       public AnExMain() {
          add(field, BorderLayout.PAGE_START);
          add(new InnerPanel(control), BorderLayout.CENTER);
       }
    
       public void fieldSetText(String text) {
          field.setText(text);
       }
    }
    
    class Control {
       private AnExMain anExMain;
       private String data = "";
    
       public Control(AnExMain anExMain) {
          this.anExMain = anExMain;
       }
    
       public void btnPressed(String actionCommand) {
          anExMain.fieldSetText("");
          if (actionCommand.equals("OK")) {
             if (data.equals("AB")) {
                anExMain.fieldSetText("Buttons pressed in proper order!");
             }
             data = "";
          } else {
             data += actionCommand;
             if (data.length() > 2) {
                data = data.substring(data.length() - 2);
             }
          }      
       }
    
    }
    
    class InnerPanel extends JPanel {
    
       public InnerPanel(final Control control) {
          JButton btnA = new JButton("A");
          JButton btnB = new JButton("B");
          JButton btnOK = new JButton("OK");
    
          add(btnA);
          add(btnB);
          add(btnOK);
    
          ActionListener listener = new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                control.btnPressed(e.getActionCommand());
             }
          };
          btnA.addActionListener(listener);
          btnB.addActionListener(listener);
          btnOK.addActionListener(listener);
       }
    }
    

    【讨论】:

    • 是的,我明白你想说什么,但在这种情况下,我认为它不会起作用。在 ATM 类中,我创建了 Jframe,以及 Screen 和 Keypad 类的一个实例(每个都有标签和其他东西)。 ATM 类将成为程序的“主”,它将调用 Keypad 类的方法 readInt()。我应该在这里得到用户介绍的号码。
    • @user1118437:对我来说效果很好。如果它不适合您,请随时告诉我们原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2012-03-05
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    相关资源
    最近更新 更多