I\'m developing an application for my computer science classes. The task is to write a calculator but without using JTextField
s or JTextArea<
Use KeyBindings and not KeyListener
Do not create your own JFrame
for a JApplet
simply call getContentPane()
on applet instance and add all your components there.
All components should be created in JApplet
overriden init()
method wrapped in a SwingUtilities#invokeAndWait(..) block
JApplet
s and Applet
s do not have a main(..)
method (besides testing purposes)
Use requestFocusInWindow()
instead of requestFocus()
I would highly suggest you read:
Here is an example works for me. It simply adds an un-editable JTextField
to the JPanel
and then adds KeyBinding
s for KeyEvent.VK_0
and KeyEvent.VK_1
to the JPanel
. If the user types either 0 or 1 it will be displayed in un-edtiable JTextField
:
import java.awt.BorderLayout;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class BinaryCalc extends JApplet {
private JTextField jtf;
@Override
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
JPanel panel = new JPanel();
setKeyBindings(panel);
jtf = new JTextField(10);
//so we cant edited it without pressing a key
jtf.setEditable(false);
panel.add(jtf);
getContentPane().add(panel, BorderLayout.CENTER);
panel.requestFocusInWindow();//incase we lost focus
}
});
} catch (InterruptedException ex) {
Logger.getLogger(BinaryCalc.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(BinaryCalc.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void setKeyBindings(final JPanel panel) {
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_0,0), "0");
panel.getActionMap().put("0", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
String tmp = jtf.getText();
jtf.setText(tmp + "0");
}
});
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1,0), "1");
panel.getActionMap().put("1", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
String tmp = jtf.getText();
jtf.setText(tmp + "1");
}
});
}
}
I took the liberty of converting @David's helpful example to use a label and the numeric keypad.
Update: This hybrid works on Ubuntu/OpenJDK, and it can be deployed via Java Web Start.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.*;
import javax.swing.*;
/**
* @see https://stackoverflow.com/a/13363349/230513
*/
public class BinaryCalc extends JApplet {
private static BinaryCalc bc = new BinaryCalc();
private JLabel label = new JLabel("0000000000");
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setTitle("BinaryCalc");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initContainer(frame);
frame.pack();
bc.label.setText("");
frame.setVisible(true);
}
});
}
// Common initialization for either JApplet or JFrame
private static void initContainer(Container container) {
JPanel panel = new JPanel();
bc.setKeyBindings(panel);
panel.add(bc.label);
container.add(panel, BorderLayout.CENTER);
panel.requestFocusInWindow();
}
@Override
public void init() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initContainer(BinaryCalc.this);
}
});
}
private void setKeyBindings(final JPanel panel) {
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_0, 0), "0");
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0, 0), "0");
panel.getActionMap().put("0", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
String tmp = label.getText();
label.setText(tmp + "0");
}
});
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "1");
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD1, 0), "1");
panel.getActionMap().put("1", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
String tmp = label.getText();
label.setText(tmp + "1");
}
});
}
}