我创建了一个计算器来帮助我练习GUI创建,因为我是新手。到目前为止它完美无缺。用户点击按钮以获得他们想要的相应号码/操作。但是,我想添加另一个功能,允许用户使用他们的键盘作为可选的输入源。通过查看KeyListener示例,看起来这可能会有所帮助......但我无法想出一种直接的方式来使用它来实现我的想法。
public class Calculator extends JFrame {
private ArrayList<JButton> numbers; // holds numerical buttons
private ArrayList<JButton> operations; // holds math operation buttons
private ArrayList<JButton> aux; // holds equals, clear and delete buttons
private JTextField answerField; // text field which displays current operands/answer
// panels for numerical, math operation and auxillary buttons
private JPanel numberPanel, functionPanel, answerPanel;
private double op1, op2; // numerical value of each operand
private String op1Str, op2Str; // current String value of each operand
private String operation; // current math operation
// true if value is set, false if not
private boolean op1HasValue, op2HasValue, operationHasValue;
private String answer; // holds current equation
public Calculator()
{
super("Java Calculator");
setLayout(new GridLayout(1, 3));
op1HasValue = op2HasValue = operationHasValue = false;
answer = "";
op1Str = "";
op2Str = "";
//create panels
numberPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
functionPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
answerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
//add number buttons to panel
numbers = new ArrayList<>();
for(int i = 0; i < 10; i++)
{
numbers.add(new JButton("" + i));
numberPanel.add(numbers.get(i));
}
// also add decimal point button
numbers.add(new JButton("."));
numberPanel.add(numbers.get(10));
// add function buttons to panel
operations = new ArrayList<>();
operations.add(new JButton("+"));
operations.add(new JButton("-"));
operations.add(new JButton("*"));
operations.add(new JButton("/"));
for(JButton button: operations)
functionPanel.add(button);
// add auxillary buttons to panel
aux = new ArrayList<>();
aux.add(new JButton("\u21D0"));
aux.add(new JButton("Clr"));
aux.add(new JButton("="));
for(JButton button: aux)
functionPanel.add(button);
// add text field to panel
answerField = new JTextField(15);
answerField.setEditable(false);
answerPanel.add(answerField);
add(numberPanel);
add(functionPanel);
add(answerPanel);
// add button listeners
myHandler handler = new myHandler();
for(JButton button: numbers)
button.addActionListener(handler);
for(JButton button: operations)
button.addActionListener(handler);
for(JButton button: aux)
button.addActionListener(handler);
}
private class myHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if((event.getActionCommand()).equals("Clr"))
{
op1HasValue = op2HasValue = operationHasValue = false;
op1Str = "";
op2Str = "";
operation = "";
answer = "";
answerField.setText("");
}
else if((event.getActionCommand()).equals("\u21D0"))
{
if(!operationHasValue)
{
if(!op1Str.isEmpty())
{
op1Str = op1Str.substring(0, op1Str.length() - 1);
answer = answer.substring(0, answer.length() - 1);
if(op1Str.isEmpty())
op1HasValue = false;
answerField.setText(answer);
}
}
else if(operationHasValue && !op2HasValue)
{
operation = "";
operationHasValue = false;
answer = answer.substring(0, answer.length() - 3);
answerField.setText(answer);
}
else
{
op2Str = op2Str.substring(0, op2Str.length() - 1);
answer = answer.substring(0, answer.length() - 1);
if(op2Str.isEmpty())
op2HasValue = false;
answerField.setText(answer);
}
} // wait for integer input event, add integer to operand #1
else if((!op1HasValue || !operationHasValue) && (numbers.contains((JButton)event.getSource())))
{
answer = answer + event.getActionCommand();
answerField.setText(answer);
op1Str = op1Str + event.getActionCommand();
op1HasValue = true;
} // wait for operation input event, save operand #1
else if(!operationHasValue && op1HasValue && operations.contains((JButton)event.getSource()))
{
op1 = Double.parseDouble(op1Str);
answerField.setText(answer + " " + event.getActionCommand() + " ");
answer = answer + " " + event.getActionCommand() + " ";
operation = event.getActionCommand();
operationHasValue = true;
} // wait for integer input event, add integer to operand #2
else if(operationHasValue && numbers.contains((JButton)event.getSource()))
{
answer = answer + event.getActionCommand();
answerField.setText(answer);
op2Str = op2Str + event.getActionCommand();
op2HasValue = true;
} // wait for equals sign input event, save operand #2, calculate answer
else if(op1HasValue && op2HasValue && operationHasValue && (event.getActionCommand()).equals("="))
{
op2 = Double.parseDouble(op2Str);
if(operation.equals("+"))
answerField.setText("" + (op1 + op2));
else if(operation.equals("-"))
answerField.setText("" + (op1 - op2));
else if(operation.equals("*"))
answerField.setText("" + (op1 * op2));
else if(operation.equals("/"))
answerField.setText("" + (op1 / op2));
answer = "";
op1HasValue = op2HasValue = operationHasValue = false;
}
}
}
答案 0 :(得分:3)
不使用KeyListener
,而是使用Key Bindings更好的主意,特别是如果您正在使用Swing。按照教程的示例,您可以尝试这样的事情(即,如果用户按下1键):
functionPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke("1"),"1 key");
functionPanel.getActionMap().put("1 key",new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
// perform operation here
}
});
这是一个更好的例子,因为你可以看到你应该在actionPerformed
方法中放置什么(例如,如果用户按下C键清除):
InputMap inMap = functionPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inMap.put(KeyStroke.getKeyStroke("C"),"Clear");
ActionMap actMap = functionPanel.getActionMap();
actMap.put("Clear",new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
op1HasValue = op2HasValue = operationHasValue = false;
op1Str = "";
op2Str = "";
operation = "";
answer = "";
answerField.setText("");
}
});
或者,如果您更愿意使用KeyListener
,则可以考虑创建一个实现KeyListener
的新类,如下所示。你必须意识到只有当指定的组件具有焦点时它才会起作用,这在其他一些方面是使用KeyListener
而不是键绑定的缺点。
KeyHandler keyHandler = new KeyHandler();
functionPanel.addKeyListener(keyHandler);
private class KeyHandler implements KeyListener {
@Override
public void keyPressed(KeyEvent ev) {
if (ev.getKeyCode() == KeyEvent.VK_C) /* C for clear */ {
op1HasValue = op2HasValue = operationHasValue = false;
op1Str = "";
op2Str = "";
operation = "";
answer = "";
answerField.setText("");
}
}
@Override
public void keyReleased(KeyEvent ev) {}
@Override
public void keyTyped(KeyEvent ev) {}
}
答案 1 :(得分:2)
通过查看KeyListener示例,似乎可能会有所帮助......
不要使用KeyListener。 Swing旨在与Key Bindings
一起使用。查看这个不同的Key Binding链接,其中显示了用于现有Swing组件的所有Key Binding。
添加另一项功能,允许用户将键盘用作可选的输入源。
使用Key Bindings
,您可以创建一个简单的Action
来输入数字:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CalculatorPanel extends JPanel
{
private JTextField display;
public CalculatorPanel()
{
Action numberAction = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
display.setCaretPosition( display.getDocument().getLength() );
display.replaceSelection(e.getActionCommand());
}
};
setLayout( new BorderLayout() );
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setBorder( new LineBorder(Color.BLACK) );
button.setPreferredSize( new Dimension(50, 50) );
buttonPanel.add( button );
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(text), text);
inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
button.getActionMap().put(text, numberAction);
}
}
private static void createAndShowUI()
{
// UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );
JFrame frame = new JFrame("Calculator Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new CalculatorPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
当然,您需要为每个算术函数创建单独的动作。