6

I'm working on a school project where we have to create a virtual smartphone, to run on a computer.

My problem is that I need to create a keyboard on the screen (like on an smartphone), which you can then use by clicking with your mouse. I could just create every single JButton, but that will take a really long time. So I was hopping that someone knew some sort of algorithm that creates all the buttons and places them correctly on the screen.

Thank you in advance :)

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
Eksperiment626
  • 985
  • 3
  • 16
  • 30

3 Answers3

9

You could construct the buttons through the use of for loops. One loop for every keyboard row is a plausible approach.

String row1 = "1234567890";
String row2 = "qwertyuiop";
// and so forth
String[] rows = { row1, row2, .. };
for (int i = 0; i < rows.length; i++) {
    char[] keys = rows[i].toCharArray();
    for (int j = 0; i < keys.length; j++) {
        JButton button = new JButton(Character.toString(keys[j]));
        // add button
    }
}
// add special buttons like space bar

This could be done more elegantly through a more OOP approach, but this basic loop system will work.

FThompson
  • 28,352
  • 13
  • 60
  • 93
  • 1
    Can't say I am really pleased with the `setSize` call and the `setLocation` call – Robin Nov 28 '12 at 22:53
  • It's the least important part of the answer; can't say it necessitates a downvote. – FThompson Nov 28 '12 at 22:56
  • 2
    An example which violates basic Swing principles, given to somebody who obviously is not yet very familiar with Java/Swing, deserves a downvote imo. Will remove my downvote now that that code is gone – Robin Nov 28 '12 at 22:58
7

This simple example might help you:

enter image description here

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


@SuppressWarnings("serial")
public class MainFrame extends JFrame
{
    private JTextField txt;
    private PopUpKeyboard keyboard;

    public MainFrame()
    {
        super("pop-up keyboard");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        txt = new JTextField(20);
        keyboard = new PopUpKeyboard(txt);

        txt.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                Point p = txt.getLocationOnScreen();
                p.y += 30;
                keyboard.setLocation(p);
                keyboard.setVisible(true);
            }
        });
        setLayout(new FlowLayout());
        add(txt);

        pack();
        setLocationByPlatform(true);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new MainFrame().setVisible(true);
            }
        });
    }

    private class PopUpKeyboard extends JDialog implements ActionListener
    {
        private JTextField txt;

        public PopUpKeyboard(JTextField txt)
        {
            this.txt = txt;
            setLayout(new GridLayout(3, 3));
            for(int i = 1; i <= 9; i++) createButton(Integer.toString(i));
            pack();
        }

        private void createButton(String label)
        {
            JButton btn = new JButton(label);
            btn.addActionListener(this);
            btn.setFocusPainted(false);
            btn.setPreferredSize(new Dimension(100, 100));
            Font font = btn.getFont();
            float size = font.getSize() + 15.0f;
            btn.setFont(font.deriveFont(size));
            add(btn);
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            String actionCommand = e.getActionCommand();
            txt.setText(txt.getText() + actionCommand);
        }
    }
}
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • +1 very nice although you might not want to extend `JFrame` class unless adding functionality, as this is considered bad practice. – David Kroukamp Nov 28 '12 at 20:20
  • 1
    +1 Also consider `Action` in preference to `ActionListener`, for [example](http://stackoverflow.com/a/5797965/230513). – trashgod Nov 28 '12 at 22:02
3
/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    String alphabet = "abcdefghijklmnopqrstuvwxyz";

    JFrame myFrame = new JFrame();
    JPanel myPanel = new JPanel();

    for (int i = 0; i < alphabet.length(); i++) {

        myPanel.add(new JButton(alphabet.substring(i, i + 1)));
    }

    myFrame.add(myPanel);
    myFrame.pack();
    myFrame.setVisible(true);

}

This is a fast example of how to do it :).

Nebri
  • 773
  • 2
  • 8
  • 21
  • 1
    This will only create one row of key buttons. I don't know of any smartphones with their keyboards laid out like so. – FThompson Nov 28 '12 at 20:12
  • 2
    that's exactly the point. This sample demonstrates the principle but at the same time it can't just be plugged into his assignment. I'm not going to do somebody's school assignment and allow them to get the credit for free. – Nebri Nov 28 '12 at 20:24