Search code examples
javaswingactionlistenernotepadvirtual-keyboard

Making a notepad in java with a on screen keyboard, cant link it to the text area properly


First of all, thank you for taking your time to read this. this is what am trying to make:

  • A Text editor with multiple options.
  • a button for a virtual keyboard. I've managed to create the buttons, also successfully added all the buttons, however I am having difficulties linking each button to my text area and making each button press work.
  • Not looking for anything complex also all other aspects of the app works, as you will see from the screenshot provided.
  • this is the bits of code in relation to my keyboard.

class KbListener implements ActionListener //kb function.
    {
        public void actionPerformed(ActionEvent e) //checking events.
        {
            keyboard = new JFrame("VK");
            keyboard.setSize(400,300);//setting initial size of app.
            keyboard.setVisible(true);//making sure its active.
            keyboard.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);//closes when the x is pressed.
            JButton[] letter = new JButton[27];
            keyboard.setLayout(new GridLayout(3,9));

            for (int i = 0;i<27;i++)
            {

                letter[i] = new JButton(""+(char)('A'+ i));

                keyboard.add(letter[i]);
                //up until this point all is fine.
                letter[i].addActionListener = (new ActionListener());


                        if(e.getSource() ==letter[A])
                        textArea.append("A");



            }

        }


    }

enter image description here


Solution

  • You need to create a String that is used in the button and used in its listener both, something like,

      for (int i = 0; i < 27; i++) {
    
         final String buttonText = String.valueOf((char) ('A' + i));
         letter[i] = new JButton(buttonText);
    
         keyboard.add(letter[i]);
         letter[i].addActionListener(new ActionListener() {
    
            @Override
            public void actionPerformed(ActionEvent e) {
               textArea.append(buttonText);
            }
         });
    
      }
    

    Note that buttonText must be final so that it is accessible within the anonymous inner ActionListener class.

    Also, consider avoiding magic numbers. For instance, you could do

    for (int i = 0; i <= (int)('Z' - 'A'); i++) {
    

    or

      int i = 0;
      for (char myChar = 'A'; myChar <= 'Z'; myChar++) {
         final String btnText = String.valueOf(myChar);
         letter[i] = new JButton(btnText);
    
         keyboard.add(letter[i]);
         letter[i].addActionListener(new ActionListener() {
    
            @Override
            public void actionPerformed(ActionEvent e) {
               textArea.append(btnText);
            }
         });
         i++;
      }
    

    Edit
    Another and perhaps better way to do this is to use Actions rather than ActionListeners. For instance,...

       //....
          int i = 0;
          for (char myChar = 'A'; myChar <= 'Z'; myChar++) {
             final String btnText = String.valueOf(myChar);
             MyKeyBoardAction action = new MyKeyBoardAction(btnText);
             letter[i] = new JButton(action);
             i++;
          }
       }
    
       private class MyKeyBoardAction extends AbstractAction {
          public MyKeyBoardAction(String name) {
             super(name);
          }
    
          @Override
          public void actionPerformed(ActionEvent e) {
             textArea.append(getValue(NAME).toString());
          }
       }
    

    You also ask about the space character,

    do u know how to add a space to the code as well?

    That would not work with your for loop but can be added on its own.

    Also,

    but why avoid the numbers?

    Because it's easy to make hard to fix bugs if you use "magic" numbers that don't intrinsically make sense. Also, by using constants, variables rather than hard-coded numbers, your variables make your code self-commenting.