I am trying to create a simple keypad and display program for learning purposes. I have it working however I am wondering if there is a better way to interact with objects in the different classes.
I have created a class called KeypadPanel that is panel with a grid layout and all of my buttons are added to it. I then created an ActionListener and attached it to the buttons with events for each button. I then added this panel to the center of a border layout panel.
Then I created a DisplayPanel class to hold a label that is added to the North section of the border layout panel. However I am still new and learning Java, so the only way I could interact with the label in the DisplayPanel is to make the label static and the setDisplay method static. Then I can call them from within the ButtonListener and change the display.
here is my code for the keypad, display and the main class
public class KeypadPanel extends JPanel {
// setup button objects
private JButton b1 = new JButton("1");
private JButton b2 = new JButton("2");
private JButton b3 = new JButton("3");
private JButton b4 = new JButton("4");
private JButton b5 = new JButton("5");
private JButton b6 = new JButton("6");
private JButton b7 = new JButton("7");
private JButton b8 = new JButton("8");
private JButton b9 = new JButton("9");
private JButton b0 = new JButton("0");
private JButton bStar = new JButton("*");
private JButton bPound = new JButton("#");
public KeypadPanel() {
// setup panel
setLayout(new GridLayout(4, 3));
setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.black));
setPreferredSize(new Dimension(150, 150));
// add listeners to buttons
b1.addActionListener(new ButtonListener());
b2.addActionListener(new ButtonListener());
b3.addActionListener(new ButtonListener());
b4.addActionListener(new ButtonListener());
b5.addActionListener(new ButtonListener());
b6.addActionListener(new ButtonListener());
b7.addActionListener(new ButtonListener());
b8.addActionListener(new ButtonListener());
b9.addActionListener(new ButtonListener());
b0.addActionListener(new ButtonListener());
bStar.addActionListener(new ButtonListener());
bPound.addActionListener(new ButtonListener());
// add buttons to panel
add(b1);
add(b2);
add(b3);
add(b4);
add(b5);
add(b6);
add(b7);
add(b8);
add(b9);
add(bPound);
add(b0);
add(bStar);
}
// setup listener for buttons
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// determine which button raised event and call setDisplay
if (e.getSource() == b1) {
DisplayPanel.setDisplay("1");
} else if (e.getSource() == b2) {
DisplayPanel.setDisplay("2");
} else if (e.getSource() == b3) {
DisplayPanel.setDisplay("3");
} else if (e.getSource() == b4) {
DisplayPanel.setDisplay("4");
} else if (e.getSource() == b5) {
DisplayPanel.setDisplay("5");
} else if (e.getSource() == b6) {
DisplayPanel.setDisplay("6");
} else if (e.getSource() == b7) {
DisplayPanel.setDisplay("7");
} else if (e.getSource() == b8) {
DisplayPanel.setDisplay("8");
} else if (e.getSource() == b9) {
DisplayPanel.setDisplay("9");
} else if (e.getSource() == b0) {
DisplayPanel.setDisplay("0");
} else if (e.getSource() == bStar) {
DisplayPanel.setDisplay("*");
} else if (e.getSource() == bPound) {
DisplayPanel.setDisplay("#");
} else {
return;
}
}
}
------------
}
public class DisplayPanel extends JPanel {
// setup display label object
private static JLabel display = new JLabel("");
public DisplayPanel() {
// setup panel and add label
setPreferredSize(new Dimension(200, 25));
setBorder(BorderFactory.createLineBorder(Color.black, 3));
add(display);
}
/**
* @param incoming
* the text to add to the display
*/
public static void setDisplay(String incoming) {
// get the incoming string and add to existing display string
String current, changed;
current = display.getText();
changed = current.concat(incoming);
display.setText(changed);
}
/**
*
* clears the current text from the display
*/
public static void clearDisplay() {
// clears display
display.setText("");
}
}
-----------------
public class KeypadTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//setup frame
JFrame frame = new JFrame ("Keypad Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//setup main panel and layout
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout(3, 3));
//create panel objects to fill frame and panel
KeypadPanel keypad = new KeypadPanel();
ClearPanel clear = new ClearPanel();
DisplayPanel display = new DisplayPanel();
// add to main panel
panel.add(display, BorderLayout.NORTH);
panel.add(keypad, BorderLayout.CENTER);
panel.add(clear, BorderLayout.EAST);
// setup frame
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
Construct the display panel, then pass it as an argument to the constructor of the keypad panel. The constructor will then store the display panel in an instance field (attribute), and the listener will use this attribute to call the setDisplay method. Of course, the setDisplay and clearDisplay methods (and the label field) should not be static. Think about it : how would it work if your application needed two different instances of your DisplayPanel?
Note that your code could be enhanced in other areas. For example, you could create only one instance of your ButtonListener, and add this unique instance as a listener of each button.
setPreferredSize should almost never be called : the preferred size is automatically computed by the layout manager, based on the components of the panel.
Finally, all the code in the main method should run in the event dispatch thread, by using SwingUtilities.invokeLater :
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// put the main code here
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With