1
\$\begingroup\$

For a school project, I had to make a keylistener that would output whatever you typed to the screen. A JFrame would be initialized to have the focus required for the listener to work. It uses delete and shift methods to determine what to type/delete. Is there any way to make this more efficient, since I have two methods that I don't use and just take up space? Any and all help is appreciated!

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

public class KeyHandler implements KeyListener {
    /*
     * KEY FUNCTIONS:
     * k.getKeyCode() returns ascii number
     * k.getKeyChar() returns char typed
     * 
     * KEY CODES:
     * [delete] 8
     * [shift] 16
     */
    private String output;

    public KeyHandler() {
        this.output = "";
    }

    public void keyPressed(KeyEvent k) {
        if(k.getKeyCode() != 8) {
            if(k.getKeyCode() != 16) {
                this.output += k.getKeyChar();
            }
        } else {
            if(this.output.length() - 1 < 0) {
                //do nothing
            } else {
                this.output = this.output.substring(0,this.output.length() - 1);
            }
        }
        this.print();
    }
    public void keyReleased(KeyEvent k) {}
    public void keyTyped(KeyEvent k) {}

    public void print() {
        System.out.print('\f'); //clear screen in BlueJ
        System.out.println(this.output);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("KeyEvent Handler");
        frame.setSize(400,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addKeyListener(new KeyHandler());
        frame.setVisible(true);
    }
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Unless you intend (and have carefully designed) for your KeyHandler to be extended, you should make it final.

If you extend KeyAdapter instead of implements KeyListener, you won’t have to implement keyReleased and keyTyped. The Adapter classes in Swing provide empty implementations of all the methods on the interface they implement, so you can just override the ones you care about.

Don’t use int values to represent more complex concepts - those are called “magic numbers”. In this case, just use the constants defined on KeyEvent, namely KeyEvent.VK_BACK_SPACE and KeyEvent.VK_SHIFT.

Put whitespace in between if and (. This visually differentiates control flow keywords from method names. Put whitespace after a , also, to make it easer to separate method arguments visually.

In keyPressed, you don’t need to declare nested if statements. Prefer &&.

Since String is immutable, a StringBuilder is preferred when doing String manipulation. You might not have covered that in class yet. It might be cleaner to use a switch statement on the value of the

It’s probably overkill to have a separate method for printing in this case.

You can clean up your logic by reversing the this.output.length() - 1 < 0 to be this.output.length() > 1 and getting rid of the empty clause.

Note that you’re deleting a character when the shift key gets pressed. Also, no matter how many times shift or delete are pressed, you’re not deleting the first character. These are both probably bugs.

You can just declare the initial value of output when you declare the variable. You don’t need a separate line in the constructor for that.

If you were to implement all my suggestions, your code might look more like:

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;

public final class KeyHandler extends KeyAdapter {

    private String output = "";
    //private final StringBuilder stringBuilder = new StringBuilder();

    public KeyHandler() {
        super();
    }

    @Override
    public void keyPressed(final KeyEvent k) {
        if ((k.getKeyCode() != KeyEvent.VK_BACK_SPACE) && (k.getKeyCode() != KeyEvent.VK_SHIFT)) {
            this.output += k.getKeyChar();
        } else if (this.output.length() > 1) {
            this.output = this.output.substring(0, this.output.length() - 1);
        }

        System.out.print('\f'); //clear screen in BlueJ
        System.out.println(this.output);

        /*
        switch (k.getKeyCode()) {
            case KeyEvent.VK_BACK_SPACE:
                if (this.output.length() > 0) {
                    this.stringBuilder.deleteCharAt(this.stringBuilder.length() - 1);
                }
                break;
            case KeyEvent.VK_SHIFT:
                break;
            default:
                this.stringBuilder.append(k.getKeyChar());
        }

        System.out.print('\f'); //clear screen in BlueJ
        System.out.println(this.stringBuilder.toString());
         */
    }

    public static void main(final String[] args) {
        final JFrame frame = new JFrame("KeyEvent Handler");
        frame.setSize(400,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addKeyListener(new KeyHandler());
        frame.setVisible(true);
    }
}
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.