1

I wrote a Java applet code using Key Event handling to demonstrate Non buffered input in Java. My code is working fine and the output is alright but I'm having trouble accomplishing another objective in this program: in the overriden keyPressed() method, I write the line: showStatus(s); , where s is the global static StringBuffer object which the characters typed from the keyboard are appended to. But the showStatus() method displays text on the status bar of the applet viewer. Therefore, the present program is usable only in an applet viewer and not in a web browser. I tried putting the statement g.drawString(String.valueOf(s),10,90); (g=Graphics class object as argument of paint()) in the paint() method to display the text in the canvas. I expected this to work as s is global and static but it's not showing any output. I used the drawString() method in paint() both with and without overriding the boolean action() method but I still didn't get anything. I just want help in displaying the typed text in the canvas of the applet.

Below is my code. Please view it for reference and to help me out the best way possible. Thank you.

/* An applet that implements the concept of non buffered user input
using Event handling method.
*/

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class NonBufferInput extends Applet implements KeyListener {
    public static StringBuffer s;

    @Override
    public void init() {
        addKeyListener(this);
        s=new StringBuffer();
    }//init

    @Override
    public void keyTyped(KeyEvent K) {}

    @Override
    public void keyPressed(KeyEvent K) {
       char c=K.getKeyChar();
       int i=K.getKeyCode();
       if(i==32)  //space bar
           s.append(' ');
       else if(i==10||i==16||i==20||i==32||i==17||i==524||i==18||i==525||i==27
             ||(i>=112&&i<=123)||i==145||i==19||i==155||i==36||i==33||i==127
             ||i==35||i==34||i==144||(i>=37&&i<=40));  //characters I don't want as input
       else if(i==8) {  //backspace
           if(s.length()!=1)
               s.setLength(s.length()-1);
       }
       else
           s.append(c);
       showStatus("Typed : "+s);
    }

    @Override
    public void keyReleased(KeyEvent K) {}

    @Override
    public void paint(Graphics g) {
        g.drawString("Text will be displayed on status bar as you type.",10,50);
        g.setColor(Color.blue);
        g.drawString(String.valueOf(s),10,80); //PROBLEM
    }//paint

    @Override
    public boolean action(Event event, Object obj) {
        repaint();
        return true;
    }//action
}//class
  • sandbox maybe? I could imagine someone using keypress() maliciously in a site – Leo Jan 15 '16 at 12:24
  • Can you really compile it? The `Graphics.drawString()` method accepts either a `String` or an `AttributedCharacterIterator` but not a `StringBuffer`... – Thomas Kläger Jan 15 '16 at 12:56
  • @Thomas Klager Hi. I'm sorry I made a mistake while typing the code here. I actually tried to display String.valueOf(s) through drawString() (I've edited the code), but I still didn't see an output. Well, is it possible to display a string from a method other that paint()? I googled it a lot but didn't come across anything. –  Jan 15 '16 at 14:57
  • @Leo what's sandbox? Sorry I'm quite a beginner to Java and I didn't understand what you said. –  Jan 15 '16 at 15:05
  • https://docs.oracle.com/javase/tutorial/deployment/applet/security.html – Leo Jan 15 '16 at 15:07
  • @Leo Okay I learned something from that. So do you suggest that this is a security issue and not related to the structure of the program? –  Jan 15 '16 at 15:18
  • I think the key here is "Therefore, the present program is usable only in an applet viewer and not in a web browser" – Leo Jan 15 '16 at 15:55

2 Answers2

2
addKeyListener(this);

Should best be:

setFocusable(true); // Sets the focusable state of this Component to the specified value.
addKeyListener(this);

Then add:

@Override
public void start() {
    requestFocusInWindow(); // Requests that this Component get the input focus ..
}//start
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Hi Andrew, Thanks for trying to help me out but I'm not a Java pro, so your code just went above my head. Thomas Klager's answer was helpful though. But thanks again :) –  Jan 16 '16 at 07:18
1

The problem is: how does the EDT (Event Dispatch Thread) know that it should repaint the applet?

It works after changing your method keyPressed to

   @Override
    public void keyPressed(KeyEvent K) {
       /* .. many lines omitted .. */
       showStatus("Typed : "+s);
       repaint(); // <<- this line is missing!
    }

As an explanation: the EDT is the thread that runs your applet. It fetches events from the event queue and dispatches them to the various event listeners. One of its responsabilities is the repainting of your components (either on request, since someone / something has changed a component) or after your component has been obscured and is now shown again.

Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • Thank you. It worked perfectly after I added the `repaint();` statement. I understood its need. One thing though: Can you tell this noob what this **"Swing thread"** is? I was thinking if it's related to the `javax.swing` package but I didn't import it in the program. –  Jan 16 '16 at 07:16
  • @ProgyadeepMoulik thanks for your comment. I tried to improve and clarify my answer. – Thomas Kläger Jan 16 '16 at 07:38
  • Thank you so much Sir :) –  Jan 16 '16 at 16:15