我正在开发一个ATM用户界面,系上一组按钮,这些按钮代表常数值,用于根据第一次选择的结果进行另一次选择。例如,如果其中一个按钮(其值代表主菜单选项中的提款)被点击并且显示包含提款金额选项的JPanel,我希望能够使用相同的按钮组各自的值来提取金额选择。目前使用代码我能够从主菜单中编写选择,只需选择提款金额,而不允许我进行选择。
public class ATM implements ActionListener{
private String[] command = {"1","2","3","4","5","6","7","8"};
private static final int BALANCE_INQUIRY = 1;
private static final int WITHDRAWAL = 5;
private static final int DEPOSIT = 2;
private static final int TRANSFER_FUND = 6;
private static final int EXIT = 3;
private int selection;
Transaction currentTransaction = null;
public ATM{
choiceButtons = new JButton[8];
for(int i = 0; i < 8; i++){
choiceButtons[i] = new JButton();
choiceButtons[i].setActionCommand(command[i]);
choiceButtons[i].setFocusable(false);
choiceButtons[i].addActionListener(this);
}
}
public void actionPerformed(ActionEvent e){
selection = Integer.parseInt(e.getActionCommand());
}
private Transaction performTransactions(){
boolean userExited = false;
while(!userExited){
switch(selection){
case BALANCE_INQUIRY:
currentTransaction = new BalanceInquiry();
currentTransaction.execute();
case WITHDRAWAL:
currentTransaction = new Withdrawal();
currentTransaction.execute();
case DEPOSIT:
currentTransaction = new Deposit();
currentTransaction.execute();
case TRANSFER_FUND:
currentTransaction = new Transfer();
currentTransaction.execute();
break;
case EXIT:
userExited = true;
break;
}
return currentTransaction;
}
}
}
public class Withdrawal extends Transaction{
private int[] amounts = {0, 10, 40, 20, 100, 60, 200};
private static final int OTHER = 7;
private static final int CANCELLED = 8;
private boolean menuOfAmountDisplayed;
public Withdrawal(){
}
public void execute(){
try{
screen.updateScreen(displayMenuOfAmounts());
Thread.sleep(5000);
menuOfAmountDisplayed = true;
performWithdrawal();
}
catch(InterruptedException e){}
}
public void performWithdrawal(){
boolean cashDispensed = false;
BankDatabase bankDatabase = getBankDatabase();
double availableBalance;
int userChoice = 0;
while(userChoice == 0){
switch(selection){
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
userChoice = amounts[selection];
break;
case OTHER:
userChoice = OTHER;
break;
case CANCELLED:
userChoice = CANCELLED;
break;
}
}
return userChoice;
}
答案 0 :(得分:1)
问题的基本答案是使用某种观察者模式,通过它可以通知你键盘的不同状态(接受/取消)。这意味着键盘执行单个作业,处理用户输入并告诉其他方用户已选择某些操作。
ActionListener
显然是这个的候选者,但是您必须编写逻辑才能使其工作(注册和事件触发代码)
这是一个过于简化的概念。它向用户显示一个菜单,当用户选择一个选项时,它会设置一个合适的状态标志并显示键盘。
当键盘触发事件时,AtmPane
会检查当前状态并根据该状态采取适当的操作。
这可以进一步扩展,专门的撤回和存款类用于管理事件,但我想提出基本的想法
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DaddyATM {
public static void main(String[] args) {
new DaddyATM();
}
public DaddyATM() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new AtmPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class AtmPane extends JPanel {
private KeyPadPane keyPadPane;
private MenuPane menuPane;
private CardLayout cardLayout;
private MenuActions menuAction = null;
public AtmPane() {
setLayout((cardLayout = new CardLayout()));
add((keyPadPane = new KeyPadPane()), "keypad");
add((menuPane = new MenuPane()), "menu");
menuPane.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (MenuActions.WITHDRAW.isEqualToCommand(cmd)) {
menuAction = MenuActions.WITHDRAW;
cardLayout.show(AtmPane.this, "keypad");
} else if (MenuActions.DEPOSIT.isEqualToCommand(cmd)) {
menuAction = MenuActions.DEPOSIT;
cardLayout.show(AtmPane.this, "keypad");
}
}
});
keyPadPane.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (KeyPadActions.ENTER.isEqualToCommand(cmd)) {
double amount = keyPadPane.getValue();
switch (menuAction) {
case WITHDRAW:
System.out.println("You withdrew " + NumberFormat.getCurrencyInstance().format(amount));
break;
case DEPOSIT:
System.out.println("You deposited " + NumberFormat.getCurrencyInstance().format(amount));
break;
}
}
cardLayout.show(AtmPane.this, "menu");
menuAction = null
}
});
cardLayout.show(this, "menu");
}
}
public enum MenuActions {
WITHDRAW("withdraw"),
DEPOSIT("deposit");
private String command;
private MenuActions(String command) {
this.command = command;
}
public boolean isEqualToCommand(String cmd) {
return command.equals(cmd);
}
public String getCommand() {
return command;
}
}
public class MenuPane extends JPanel {
public MenuPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(new JButton(new MenuAction("Withdraw", MenuActions.WITHDRAW)), gbc);
add(new JButton(new MenuAction("Deposit", MenuActions.DEPOSIT)), gbc);
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
protected void fireActionPerformed(MenuActions action) {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, action.getCommand());
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
public class MenuAction extends AbstractAction {
private MenuActions action;
public MenuAction(String name, MenuActions action) {
this.action = action;
putValue(NAME, name);
}
@Override
public void actionPerformed(ActionEvent e) {
fireActionPerformed(action);
}
}
}
public enum KeyPadActions {
ENTER("enter"),
CANCELED("canceled");
private String command;
private KeyPadActions(String command) {
this.command = command;
}
public boolean isEqualToCommand(String cmd) {
return command.equals(cmd);
}
public String getCommand() {
return command;
}
}
public class KeyPadPane extends JPanel {
private JButton[] numbers;
private JButton cancel, clear, enter;
private JFormattedTextField amountField;
public KeyPadPane() {
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
amountField = new JFormattedTextField(currencyFormat);
amountField.setColumns(10);
amountField.setHorizontalAlignment(JFormattedTextField.RIGHT);
amountField.setValue(0d);
amountField.setEditable(false);
numbers = new JButton[10];
for (int index = 0; index < numbers.length; index++) {
numbers[index] = new JButton(new NumberAction(index));
}
setLayout(new BorderLayout());
GridBagConstraints gbc = new GridBagConstraints();
add(amountField, BorderLayout.NORTH);
JPanel buttons = new JPanel(new GridLayout(0, 4));
List<Component> components = new ArrayList<>();
components.add((cancel = new JButton(new CancelAction())));
components.add((clear = new JButton(new ClearAction())));
components.add((enter = new JButton(new EnterAction())));
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
buttons.add(numbers[(row * 3) + (col + 1)]);
}
buttons.add(components.get(row));
}
buttons.add(new JButton());
buttons.add(numbers[0]);
buttons.add(new JButton());
buttons.add(new JButton());
add(buttons);
}
public double getValue() {
return (double) amountField.getValue();
}
public void append(int number) {
Double objValue = (Double) amountField.getValue();
StringBuilder sb = new StringBuilder(Double.toString(objValue));
sb.insert(sb.indexOf("."), number);
amountField.setValue(Double.parseDouble(sb.toString()));
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
public void clear() {
amountField.setValue(0d);
}
public void enter() {
fireActionPerformed(KeyPadActions.ENTER);
clear();
}
public void cancel() {
fireActionPerformed(KeyPadActions.CANCELED);
clear();
}
protected void fireActionPerformed(KeyPadActions action) {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, action.getCommand());
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
public class ClearAction extends AbstractAction {
public ClearAction() {
putValue(NAME, "Clear");
}
@Override
public void actionPerformed(ActionEvent e) {
clear();
}
}
public class EnterAction extends AbstractAction {
public EnterAction() {
putValue(NAME, "Enter");
}
@Override
public void actionPerformed(ActionEvent e) {
enter();
}
}
public class CancelAction extends AbstractAction {
public CancelAction() {
putValue(NAME, "Cancel");
}
@Override
public void actionPerformed(ActionEvent e) {
cancel();
}
}
public class NumberAction extends AbstractAction {
private int number;
public NumberAction(int number) {
this.number = number;
putValue(NAME, Integer.toString(number));
}
@Override
public void actionPerformed(ActionEvent e) {
append(number);
}
}
}
}