In a program I'm attempting to make, there are three text field accompanied by several buttons (each representing a number). I'm trying to get it so you can type by clicking on the buttons (as opposed to the keyboard). So far, I got this:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.*;
public class GUI extends JFrame {
private JButton[] numPad = new JButton[10];
private JTextField totalBill = new JTextField();
private JTextField totalPeople = new JTextField();
private JTextField tipPercentage = new JTextField();
private JTextField tipAmount = new JTextField();
private JTextField grandTotal = new JTextField();
private JTextField totalPerPerson = new JTextField();
private JButton doneButton = new JButton("Done");
private JButton clearButton = new JButton("Clear");
////////////////////////////////////////////////////////////////////////
private JPanel superContainer;
private JPanel container;
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel();
public GUI() {
//Set JFrame title.
super("Tip Calculator");
superContainer = new JPanel();
superContainer.setLayout(new BoxLayout(superContainer, BoxLayout.Y_AXIS));
//Create a container to hold two GridLayouts beside one another.
container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
//Create panels to be placed in container panel.
panel1.setPreferredSize(new Dimension(500, 250));
panel1.setLayout(new GridLayout(4,3,10,10));
panel2.setPreferredSize(new Dimension(500, 250));
panel2.setLayout(new GridLayout(7,2,10,10));
//Populate all the JButtons for the numPad.
for (int i=0; i<=9; i++) {
numPad[i] = new JButton(Integer.toString(i));
}
//Place each numPad button on the first JPanel.
for (int i=1; i<=9; i++) {
panel1.add(numPad[i]);
}
panel1.add(numPad[0]);
//Populate second GridLayout.
panel2.add(new JLabel("Total Bill: "));
panel2.add(totalBill);
panel2.add(new JLabel("Total People: "));
panel2.add(totalPeople);
panel2.add(new JLabel("Total Percentage: "));
panel2.add(tipPercentage);
panel2.add(doneButton);
panel2.add(clearButton);
panel2.add(new JLabel("Tip Amount: "));
panel2.add(tipAmount);
panel2.add(new JLabel("Grand Total: "));
panel2.add(grandTotal);
panel2.add(new JLabel("Total/Person: "));
panel2.add(totalPerPerson);
grandTotal.setEditable(false);
tipAmount.setEditable(false);
totalPerPerson.setEditable(false);
//Add the first GridLayout panel to the container.
container.add(panel1);
//Create a space between the GridLayout panels.
container.add(Box.createRigidArea(new Dimension(30,0)));
//Add the second GridLayout panel to the container.
container.add(panel2);
//Same as above but with title ontop and container panel below.
superContainer.add(new JLabel("Title"));
superContainer.add(Box.createRigidArea(new Dimension(0,30)));
superContainer.add(container);
//The panel the JFrame uses.
this.setContentPane(superContainer);
TheHandler handler = new TheHandler();
doneButton.addActionListener(handler);
clearButton.addActionListener(handler);
}
private class TheHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource()==doneButton) {
tipAmount.setText(Double.toString(Double.parseDouble(totalBill.getText()) * (Double.parseDouble(tipPercentage.getText()) / 100)));
grandTotal.setText(Double.toString(Double.parseDouble(tipAmount.getText()) + Double.parseDouble(totalBill.getText())));
totalPerPerson.setText(Double.toString(Double.parseDouble(grandTotal.getText()) / Double.parseDouble(totalPeople.getText()))); }
else if (e.getSource()==clearButton) {
grandTotal.setText("");
tipAmount.setText("");
totalPerPerson.setText("");
totalBill.setText("0");
tipPercentage.setText("0");
totalPeople.setText("1");
totalBill.requestFocus();
totalBill.selectAll(); }
}
}
}
After searching the Internet, I came across the following code:
private class AddDigit extends TextAction {
private String digit;
public AddDigit(String digit) {
super( digit );
this.digit = digit;
}
public void actionPerformed(ActionEvent e) {
JTextComponent component = getFocusedComponent();
component.replaceSelection( digit );
}
}
The only problem is, I have no clue how to use the code I found (the code I found being the second block).
If you don't "expect" the user to use the keyboard to navigate the buttons, then I would simply make them unfocusable. This way, the user can click the button, but the currently active field will not lose focus. The user can either type directly into the field or click the numpad...
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.JTextComponent;
public class TestNumPad {
public static void main(String[] args) {
new TestNumPad();
}
public TestNumPad() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JTextField field = new JTextField(10);
add(field, gbc);
add(new NumPad(), gbc);
field.requestFocusInWindow();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class NumPad extends JPanel {
private ActionHandler actionHandler;
public NumPad() {
setLayout(new GridLayout(4, 3));
actionHandler = new ActionHandler();
for (int index = 1; index < 10; index++) {
add(createButton(index));
}
add(new JPanel());
add(createButton(0));
add(new JPanel());
}
protected JButton createButton(int index) {
JButton btn = new JButton(String.valueOf(index));
btn.setFocusable(false);
btn.addActionListener(actionHandler);
return btn;
}
public class ActionHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof JButton) {
JButton btn = (JButton) source;
try {
int value = Integer.parseInt(btn.getText().trim());
Component comp = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (comp instanceof JTextComponent) {
JTextComponent tc = (JTextComponent) comp;
tc.setText(tc.getText() + value);
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
}
}
}