KeyListener: Wiederholtes Aufrufen von KeyPressed verhindern

giggei

Grünschnabel
Hi Leute,

hab folgendes Problem und auch nach ewigem Suchen noch keine Lösung gefunden:

Ich muss ein Programm Coden, das alle Keycodes mitloggt und dann speichert.
Nun habe ich aber das Problem das die Methode keyPressed des KeyListeners ständig aufgerufen wird wenn ich länger auf einer Taste bleibe (z.B. Shift wenn ein ganzes Wort groß geschrieben wird).

Ich will aber natürlich jede Taste bei einmaligem drücken (auch wenns länger dauert) nur einmal loggen,
gibts ne Möglichkeit das zu realisieren?

Hätt schon versucht einen boolean einzubauen der erst beim keyReleased Event wieder true wird, aber dann loggt er nicht richtig wenn Tasten gleichzeitig gedrückt werden (z.b. wieder beim groß schreiben mit shift)....

Und eine weitere Frage hätt ich noch:

Gibts eine Möglichkeit linke und rechte Shift taste zu unterscheiden? Denn beide liefern den Keycode 16.

gruss gig
 
Hi,

ich hab versucht dein Problem auszuprogrammieren, ich hoffe du hast es so gemeint.

Meine Lösung war, dass ich einfach jede Taste speichert bis sie losgelassen wird. Somit ist sichergestellt, dass sie nur einmal geloggt wird, egal wie oft und lange sie gedrückt wird.

Hier der Code:
Java:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

/**
 * Loggt die eingaben einer Tastatur mit Hilfe des AWT Listeners java.awt.KeyListener .
 * Der Logger ist im Stande auf jeden beliebigen Stream zu loggen (Standardausgabe, Datei, TCP-Stream etc.)
 * @author Yanick Dickbauer
 */
public class KeyLogger implements KeyListener {
	
	/** Hier kommen die Keys rein die gedrückt wurden, jedoch noch nicht losgelassen wurden */
	private ArrayList<Key> keys;
	
	/** Die ganzen Streams in die geloggt werden soll */
	private ArrayList<PrintWriter> streams;
	
	public KeyLogger(){
		init();
		streams.add(new PrintWriter(System.out));
	}
	
	public KeyLogger(OutputStream ... streams){
		init();
		for (OutputStream os : streams)
			this.streams.add(new PrintWriter(os));
	}
	
	private void init(){
		keys = new ArrayList<Key>();
		streams = new ArrayList<PrintWriter>();
	}

	public void keyPressed(KeyEvent ev) {
		Key pressed = new Key(ev.getKeyChar(), ev.getKeyCode(), ev.getKeyLocation());
		if (!keys.contains(pressed)){
			keys.add(pressed);
			logKey(pressed);
		}
			
	}

	public void keyReleased(KeyEvent ev) {
		Key released = new Key(ev.getKeyChar(), ev.getKeyCode(), ev.getKeyLocation());
		keys.remove(released);
	}

	public void keyTyped(KeyEvent ev) {
	}
	
	public void logKey(Key key){
		Calendar now = Calendar.getInstance();
		SimpleDateFormat formatter = new SimpleDateFormat("E yy-MM-dd 'on' HH:mm:ss zzz");
		String logText = String.format("%s \t%s", formatter.format(now.getTime()), key);
		for (PrintWriter writer : streams){
			writer.println(logText);
			writer.flush();
		}
	}
	
	class Key{
		char c;
		int code, location;
		
		private String keyString;
		
		Key(char c, int code, int location){
			this.c = c;
			this.code = code;
			this.location = location;
			getKeyString();
		}
		
		private void getKeyString(){
			if (Character.isLetterOrDigit(code)){
				keyString = String.valueOf(c);
				return;
			}
				
			switch (code){
			case 27:
				keyString = "ESC"; return;
			case 10:
				keyString = "ENTER"; return;
			case 32:
				keyString = "SPACE"; return;
			case 16:
				keyString = "SHIFT"; return;
			}
			keyString = String.valueOf(code);	
		}
		
		public String toString(){
			return String.format("Key: '%s', Code: %d, Location: %d", keyString, code, location);
		}
		
		/**
		 * Zwei Keys sind dann gleich, wenn Code und Location übereinstimmen
		 */
		public boolean equals(Object two){
			if (! (two instanceof Key)) return false;
			
			Key keyTwo = (Key)two;
			if (keyTwo.code == code && keyTwo.location == location)
				return true;
			
			return false;
		}
	}

}


Lg, Yanick
 
Vielen Dank für die spitzen Antwort.

Also die idee mit der liste is genial, hab ich so ähnlich umgesetzt.
vielen dank jetzt klappt alles!

gruss gig
 
Zurück