I need some help. I'm trying to create a number pad like a cellphone that captures user input by pressing buttons in a panel on the left and displaying what the user punches in the top panel. Then I have a clear button in the panel on the right to clear all, but I can't get it to work. Am I close?

package keypad;

import java.awt.*;
import javax.swing.*;
import javax.swing.JLabel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class KeyPadPanel extends JFrame implements ActionListener
{
    private JLabel display;
    private JButton one, two, three, four, five, six, seven, eight, nine, zero,
            asterick, pound, clear;
    private JPanel pad, title;
    
    public KeyPadPanel()
    {
        setLayout (new BorderLayout());
        setBackground(Color.BLACK);
        
        display = new JLabel("Key Pad");
        
        title = new JPanel();
        title.setLayout(new BorderLayout());
        title.add(display);
        add(title, BorderLayout.NORTH);
       
        pad = new JPanel();
        pad.setBackground(Color.DARK_GRAY);
        pad.setPreferredSize(new Dimension (150,168));
       
        one = new JButton ("1");
        one.addActionListener(this);
        two = new JButton ("2");
        two.addActionListener(this);
        three = new JButton ("3");
        three.addActionListener(this);
        four = new JButton ("4");
        four.addActionListener(this);
        five = new JButton ("5");
        five.addActionListener(this);
        six = new JButton ("6");
        six.addActionListener(this);
        seven = new JButton ("7");
        seven.addActionListener(this);
        eight = new JButton ("8");
        eight.addActionListener(this);
        nine = new JButton ("9");
        nine.addActionListener(this);
        zero = new JButton ("0");
        zero.addActionListener(this);
        asterick = new JButton ("*");
        asterick.addActionListener(this);
        pound = new JButton ("#");
        pound.addActionListener(this);

        pad.add(one);
        pad.add(two);
        pad.add(three);
        pad.add(four);
        pad.add(five);
        pad.add(six);
        pad.add(seven);
        pad.add(eight);
        pad.add(nine);
        pad.add(asterick);
        pad.add(zero);
        pad.add(pound);
        
        JPanel clearPane = new JPanel();
        clear = new JButton ("CLR");
        clearPane.setBackground(Color.DARK_GRAY);
        clearPane.setPreferredSize( new Dimension(50, 50));
        Component add = clearPane.add(clear);
        
        add(pad, BorderLayout.CENTER);
        add(clearPane, BorderLayout.EAST);
    }
    
    public void actionPerformed(ActionEvent e)
    {
        System.out.println(((JButton)e.getSource()).getText());
    }
}

My Driver

package keypad;

import javax.swing.*;
import java.awt.Container.*;

public class KeyPad 
{

    public static void main(String[] args) 
    {
      JFrame frame = new JFrame ("KeyPad");
      frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
      
      frame.getContentPane().add(new KeyPadPanel());
      frame.pack();
      frame.setVisible(true);
    }
}

Recommended Answers

All 7 Replies

Ive got a question first. Are you using a JLabel for display? ok.

Well, Youve got the frame creation part correct. BUt You need to change the actionPerformed method.

Use String getActionCommand() method to see which button was clicked.
First check if "CLR" was clicked, if so then set the text of the JLable (display) to "" (empty string) using setText().
Else if CLR was not clicked, get the already existing code and append it with the pressed key.

something like,

display.setText(display.getText()+command);

And btw, u forgot to add the actionListener object to CLR button.

where command is the String where u store whatever is returned by getActionCommand()

Thanks,
I think after reading your comments, I need to go back and make a class for each panel to better control how each is handled.

That's almost certainly a good idea. The code for GUIs with lots of controls like this gets out of hand very quickly; it's very long, horrible to debug, and incomprehensible for anyone else. Splitting it into separate classes for each panel helps enormously.
One hint: Keep a class for the whole window, and make the panel classes sub-classes of it. That way the panel classes have access to the class variables and methods of the window class. You can use that to handle anything that needs to be shared or communicated between the panels. Any methods that can't be handled within just one panel can go up in the window class.

OK. good luck. Mark thread solved it it seems ok for u.

I went back to the drawing board so-to-speak to create a panel class for each panel I want in my app. I don't think I've made things any better. I obviously am not grasping the whole passing data from panel class to panel class (or anything related to displaying JPanels for that matter). Below is what I have so far.

Main driver

import javax.swing.*;
import java.awt.*;

public class KeyPad extends JFrame
{

    public static void main(String[] args) 
    {
      JFrame frame = new JFrame ("KeyPad");
      frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
      
      JPanel kp = new JPanel();
      kp.setBorder(BorderFactory.createEtchedBorder());
      kp.add(new KeyPadPanel());
      
      JPanel dis = new JPanel();
      dis.setBorder(BorderFactory.createEtchedBorder());
      dis.add(new DisplayPanel());
      
      JPanel cp = new JPanel();
      cp.setBorder(BorderFactory.createEtchedBorder());
      cp.add(new ClearPanel());
      
      frame.getContentPane().add(kp, BorderLayout.CENTER);
      frame.getContentPane().add(dis, BorderLayout.NORTH);
      frame.getContentPane().add(cp, BorderLayout.EAST);
      frame.pack();
      frame.setVisible(true);
    }
}

My panel classes

import java.awt.*;
import javax.swing.JPanel.*;
import javax.swing.*;
import java.awt.Container.*;
import java.awt.event.*;


public class KeyPadPanel extends JPanel
{
    private String[] keys = { "1", "2", "3",
                              "4", "5", "6",
                              "7", "8", "9",
                              "*", "0", "#"};
    
    private String display;

    class KeyPad extends JPanel 
    {
        Button[] b = new Button[keys.length];
        
        public KeyPad()
        {
            KeyPad p = new KeyPad();
            setLayout(new GridLayout(4,3));
            setBackground(Color.BLACK);
            p.setSize(new Dimension(175, 175));
            
            add(p);
            
            for (int i=0; i<keys.length; i++)
            {
                b[i] = new Button(keys[i]);
                p.add(b[i]);
                b[i].addActionListener(this);  //I get an error on "this" not sure why?
            }
        }  
    }
    
    public void actionPerformed(ActionEvent e)
    {
        display = display + e.getSource();
    }
    
    public String getDisplay()
    {
        return display;
    }
}


import java.awt.*;
import javax.swing.JPanel.*;
import javax.swing.*;
import java.awt.Container.*;

public class DisplayPanel extends JPanel
{
    public void init()
    {
        Display d = new Display();
        add(d);
    }
    
    class Display extends JPanel
    {
        public Display()
        {
            JPanel display = new JPanel();
            display.setBackground(Color.GRAY);
            display.setPreferredSize(new Dimension(200, 15));
            
            JLabel output = new JLabel();
            display.add(output, BorderLayout.CENTER);
            
        }
    }
    
}

import javax.swing.JPanel.*;
import javax.swing.*;
import java.awt.*;

public class ClearPanel extends JPanel
{
    public void init()
    {
        Clear c = new Clear();
        add(c);
    }
    
    class Clear extends JPanel
    {
        public Clear()
        {
            JPanel clear = new JPanel();
            JButton bClear = new JButton("Clear");
            clear.setSize(new Dimension(175, 175));
            
        }
    }
}

Any one who can help me or point me to an app that at least does something similar so I can understand how this is supposed to interact would be greatly appreciated.

I think you are over elaborating this.

Create a frame class extending JFrame.

Create a panels. Add buttons to one panel and display to another panel. Keep these panel classes as Inner classes of the mainFrame class.

Now create a listener class that inplements action listener as another inner class of Main Frame class so that it can access the private data of MainFrame class (display label). Now code action performed with the code I gave. Thats all. No need for init() and all. Just use constructors of the panel classes to construct them. and then in the constructor of the MainFrame class add those panels.

And in the main driver just instantiate MainFrame and ure done!

^ like Stevanity says. Especially make your new classes inner classes of class KeyPad (ie define them inside the { and } of class KeyPad. If you make them separate public classes outside class KeyPad then you will need some extra code to give them access to the vars and methods of class KeyPad.
and...

JPanel kp = new JPanel();
kp.setBorder(BorderFactory.createEtchedBorder());
kp.add(new KeyPadPanel());

Since KeyPadPanel is JPanel there's no need to put it inside yet another panel. You can simply add it directly...

JPanel kp = new KeyPadPanel();
// set the border inside KeyPadPanel's constructor, not here 
...
frame.add(kp, BorderLayout.CENTER); // you haven't needed the .getContentPane() since Java 1.5
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.