Yet another KeyListener question
I'm trying to implement KeyListeners for a simple Calculator program, to catch key typed events from the numeric keypad. So far I've done the following:
added implements KeyListener to the class header
added KeyListeners to each JButton
made the Panel that the JButton array resides in focusable
added the code for the Panel to request focus when the Calculator window is selected:
addWindowListener(new WindowAdapter(){
publicvoid windowActivated(WindowEvent e){
keypad.requestFocusInWindow();
}
});
added KeyTyped, KeyPressed, and KeyReleased methods to the class
the (incomplete) KeyTyped method, which uses code from the Sun tutorial, so far is:
publicvoid keyTyped(KeyEvent e)
{
int id = e.getID();
if (id == KeyEvent.KEY_TYPED){
char c = e.getKeyChar();
int keyNum = (int)c;
switch (keyNum)
{
case 48:case 96:
keys[0].doClick(100);
break;
case 49:case 97:
keys[1].doClick(100);
break;
case 50:case 98:
keys[2].doClick(100);
break;
}
}
}
So far, the implementation of the KeyListener doesn't appear to do anything.
What have I missed so far? Is the enclosing Panel of the JButton array the correct component to be requesting focus? Is there an error in the keyTyped method?
and here is the complete code for your enjoyment:
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
import javax.swing.JButton;//ADDED
publicclass Calculatorextends Frameimplements ActionListener, KeyListener
{
private JButton keys[];//CHANGED Button to JButton
private Panel keypad;
private TextField lcd;
privatedouble op1;
privateboolean first;
privateboolean foundKey;
privateboolean clearText;
privateint lastOp;
private DecimalFormat calcPattern;
public Calculator()
{
//
MenuBar mnuBar =new MenuBar();
setMenuBar(mnuBar);
//
Menu mnuFile =new Menu("File",true);
mnuBar.add(mnuFile);
MenuItem mnuFileExit =new MenuItem("Exit");
mnuFile.add(mnuFileExit);
//
Menu mnuEdit =new Menu("Edit",true);
mnuBar.add(mnuEdit);
MenuItem mnuEditClear =new MenuItem("Clear");
mnuEdit.add(mnuEditClear);
mnuEdit.addSeparator();
MenuItem mnuEditCopy =new MenuItem("Copy");
mnuEdit.add(mnuEditCopy);
MenuItem mnuEditPaste =new MenuItem("Paste");
mnuEdit.add(mnuEditPaste);
//
Menu mnuAbout =new Menu("About",true);
mnuBar.add(mnuAbout);
MenuItem mnuAboutCalculator =new MenuItem("About Calculator");
mnuAbout.add(mnuAboutCalculator);
//
mnuFileExit.addActionListener(this);
mnuEditClear.addActionListener(this);
mnuEditCopy.addActionListener(this);
mnuEditPaste.addActionListener(this);
mnuAboutCalculator.addActionListener(this);
//
mnuFileExit.setActionCommand("Exit");
mnuEditClear.setActionCommand("Clear");
mnuEditCopy.setActionCommand("Copy");
mnuEditPaste.setActionCommand("Paste");
mnuAboutCalculator.setActionCommand("About");
//
lcd =new TextField(20);
lcd.setEditable(false);
keypad =new Panel();
keypad.setFocusable(true);//ADDED
keys =new JButton[24];
first =true;
op1 = 0.0;
clearText =true;
lastOp = 0;
calcPattern =new DecimalFormat("########.########");
//populate keys array with JButtons
for(int i = 0; i<=9; i++)
keys[i] =new JButton(String.valueOf(i));
keys[10] =new JButton("/");
keys[11] =new JButton("*");
keys[12] =new JButton("-");
keys[13] =new JButton("+");
keys[14] =new JButton("=");
keys[15] =new JButton(".");
keys[16] =new JButton("M+");
keys[17] =new JButton("M-");
keys[18] =new JButton("M*");
keys[19] =new JButton("M/");
keys[20] =new JButton("MR");
keys[21] =new JButton("MC");
keys[22] =new JButton("Back");
keys[23] =new JButton("Clear");
//
setLayout(new BorderLayout());
keypad.setLayout(new GridLayout(6,4,10,10));
for (int i=7; i<=10; i++)
keypad.add(keys[i]);
for (int i=4; i<=6; i++)
keypad.add(keys[i]);
keypad.add(keys[11]);
for(int i=1; i<=3; i++)
keypad.add(keys[i]);
keypad.add(keys[12]);
keypad.add(keys[0]);
for (int i=15; i>=13; i--)
keypad.add(keys[i]);
for (int i=16; i<24; i++)
keypad.add(keys[i]);
for(int i=0; i<keys.length; i++)
{
keys[i].addActionListener(this);
keys[i].addKeyListener(this);
}
add(lcd, BorderLayout.NORTH);
add(keypad, BorderLayout.CENTER);
//ADDED - keypad panel requests focus when window is active
// not sure this is the correct component to request focus
addWindowListener(new WindowAdapter(){
publicvoid windowActivated(WindowEvent e){
keypad.requestFocusInWindow();
}
});
addWindowListener(
new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}// end of constructor method
publicvoid actionPerformed(ActionEvent e)
{
//test for menu item clicks
String arg = e.getActionCommand();
if (arg =="Exit")
System.exit(0);
if (arg =="Clear")
{
clearText =true;
first =true;
op1 = 0.0;
lcd.setText("");
lcd.requestFocus();
}
if (arg =="Copy")
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection contents =new StringSelection(lcd.getText());
cb.setContents(contents,null);
}
if (arg =="Paste")
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = cb.getContents(this);
try
{
String s = (String)content.getTransferData(DataFlavor.stringFlavor);
lcd.setText(calcPattern.format(Double.parseDouble(s)));
}
catch (Throwable exc)
{
lcd.setText("");
}
}
if (arg =="About")
{
String message ="Calculator ver. 1.0\nOpenExhibit Software\nCopyright 2004\nAll rights reserved";
JOptionPane.showMessageDialog(null, message,"About Calculator", JOptionPane.INFORMATION_MESSAGE);
}
//test for button clicks
foundKey =false;
//search for the clicked key
for (int i = 0; i><keys.length && !foundKey; i++)
{
if (e.getSource() == keys[i])
{
foundKey =true;
switch(i)
{
//number and decimal point buttons
case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 15:
if (clearText)
{
lcd.setText("");
clearText =false;
}
lcd.setText(lcd.getText()+ keys[i].getText());
break;
//operator buttons
case 10:case 11:case 12:case 13:case 14:
clearText =true;
if (first)//first operand
{
if(lcd.getText().length()==0) op1 = 0.0;
else op1 = Double.parseDouble(lcd.getText());
first =false;
//clearText = true;
lastOp = i;
}
else//second operand
{
switch(lastOp)
{
case 10:
op1 /= Double.parseDouble(lcd.getText());
break;
case 11:
op1 *= Double.parseDouble(lcd.getText());
break;
case 12:
op1 -= Double.parseDouble(lcd.getText());
break;
case 13:
op1 += Double.parseDouble(lcd.getText());
break;
}//end of switch(lastOp)
lcd.setText(calcPattern.format(op1));
//clearText = true;
if (i==14) first =true;
else lastOp = i;
}// end else
break;
//Add to memory button
case 16:
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = cb.getContents(this);
try
{
//get contents of clipboard
String s = (String)content.getTransferData(DataFlavor.stringFlavor);
//parse contents of clipboard into Double
Double d = Double.parseDouble(s);
//get contents of lcd, parse into Double and add to clipboard value
d += Double.parseDouble(lcd.getText());
//convert Double value into StringSelection
StringSelection contents =new StringSelection(d.toString());
//set clipboard contents
cb.setContents(contents,null);
clearText =true;
}
catch (Throwable exc)
{
lcd.setText("");
}
break;
}
//Subtract from memory button
case 17:
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = cb.getContents(this);
try
{
//get contents of clipboard
String s = (String)content.getTransferData(DataFlavor.stringFlavor);
//parse contents of clipboard into Double
Double d = Double.parseDouble(s);
//get contents of lcd, parse into Double and subtract from clipboard value
d -= Double.parseDouble(lcd.getText());
//convert Double value into StringSelection
StringSelection contents =new StringSelection(d.toString());
//set clipboard contents
cb.setContents(contents,null);
clearText =true;
}
catch (Throwable exc)
{
lcd.setText("");
}
break;
}
//Multiply with memory contents button
case 18:
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = cb.getContents(this);
try
{
//get contents of clipboard
String s = (String)content.getTransferData(DataFlavor.stringFlavor);
//parse contents of clipboard into Double
Double d = Double.parseDouble(s);
//get contents of lcd, parse into Double and multiply with clipboard value
d *= Double.parseDouble(lcd.getText());
//convert Double value into StringSelection
StringSelection contents =new StringSelection(d.toString());
//set clipboard contents
cb.setContents(contents,null);
clearText =true;
}
catch (Throwable exc)
{
lcd.setText("");
}
break;
}
//Divide by memory contents button
case 19:
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = cb.getContents(this);
try
{
//get contents of clipboard
String s = (String)content.getTransferData(DataFlavor.stringFlavor);
//parse contents of clipboard into Double
Double d = Double.parseDouble(s);
//get contents of lcd, parse into Double and divide by clipboard value
d /= Double.parseDouble(lcd.getText());
//convert Double value into StringSelection
StringSelection contents =new StringSelection(d.toString());
//set clipboard contents
cb.setContents(contents,null);
clearText =true;
}
catch (Throwable exc)
{
lcd.setText("");
}
break;
}
//Paste from memory button
case 20:
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = cb.getContents(this);
try
{
String s = (String)content.getTransferData(DataFlavor.stringFlavor);
lcd.setText(calcPattern.format(Double.parseDouble(s)));
}
catch (Throwable exc)
{
lcd.setText("");
}
break;
}
//Clear memory button
case 21:
{
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Double d = 0.0;
StringSelection contents =new StringSelection(d.toString());
cb.setContents(contents,null);
break;
}
//Backspace button
case 22:
{
lcd.setText(lcd.getText().substring(0, lcd.getText().length()-1));
break;
}
//Clear button
case 23:
{
clearText =true;
first =true;
op1 = 0.0;
lcd.setText("");
lcd.requestFocus();
break;
}
}// end of switch(i)
}// end of if
}// end of for
}// end of actionPerformed() method
//ADDED - and not working
publicvoid keyTyped(KeyEvent e)
{
int id = e.getID();
if (id == KeyEvent.KEY_TYPED){
char c = e.getKeyChar();
int keyNum = (int)c;
switch (keyNum)
{
case 48:case 96:
keys[0].doClick(100);
break;
case 49:case 97:
keys[1].doClick(100);
break;
case 50:case 98:
keys[2].doClick(100);
break;
}
}
}
publicvoid keyPressed(KeyEvent e)
{
}
publicvoid keyReleased(KeyEvent e)
{
}
publicstaticvoid main(String args[])
{
//set frame properties
Calculator f =new Calculator();
f.setTitle("Calculator application");
f.setBounds(200, 200, 300, 300);
f.setVisible(true);
//set image properties and add to Frame
Image icon = Toolkit.getDefaultToolkit().getImage("calcImage.gif");
f.setIconImage(icon);
}// end of main
}// end of class
Thanks in advance!>

