# KeyListener ohne Focus - Wie?



## Schrubber (30. Okt 2012)

Hallo,

ich schreibe derzeit an einem kleinen Hilfstool für ein Online-Spiel. Hierzu benötige ich die Möglichkeit, aus dem Spiel heraus über den KeyListener meines Programmes 6 verschiedene Tasten zu identifizieren und Aktionen auf die Betätigung auszuführen. 

Das Programm funktioniert komplett, wenn das Fenster den Focus hat. Jedoch möchte ich nicht, dass ich jedesmal, wenn ich die Taste drücken will, auf den Desktop muss. Denn das kann in gefährlichen Situtationen Ingame zu einer Niederlage führen...

Vielleicht kann mir da jemand helfen?  Wäre echt nett.

Hier mein Code:


```
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
public class LoL_Timer implements MouseListener, MouseMotionListener, KeyListener {
	private JLabel baronPic, baronLabel, dragonPic, dragonLabel, lizardPic, lizardLabel, golemPic, golemLabel;
	private BufferedImage baronNashor, dragon, lizard, golem;
	private int X,Y;
	private int delay = 0;
	private int period = 1000;
	private Timer timer = new Timer();
	private JDialog dialog;
	private int baronTime = 420;
	private int dragonTime = 360;
	private int lizardTime = 300;
	private int golemTime = 300;
	private int baronCounter, dragonCounter, lizardCounter, golemCounter;
	
	public static void main(String[] args) {
		new LoL_Timer();
	}
	
	public LoL_Timer() {
		try {
			baronNashor = ImageIO.read(new File("C:\\Users\\Schrubber\\Desktop\\LoL_Timer\\images\\Baron_Nashor.png"));
			dragon = ImageIO.read(new File("C:\\Users\\Schrubber\\Desktop\\LoL_Timer\\images\\Dragon.png"));
			lizard = ImageIO.read(new File("C:\\Users\\Schrubber\\Desktop\\LoL_Timer\\images\\Lizard.png"));
			golem = ImageIO.read(new File("C:\\Users\\Schrubber\\Desktop\\LoL_Timer\\images\\Golem.png"));
			
			baronPic = new JLabel(new ImageIcon( baronNashor ));
			dragonPic = new JLabel(new ImageIcon( dragon ));
			lizardPic = new JLabel(new ImageIcon( lizard ));
			golemPic = new JLabel(new ImageIcon( golem ));
			
			/* Images, wenn das Progamm als .jar ausgeführt werden soll */
			//baronNashor = ImageIO.read(new File("images/Baron_Nashor.png"));
			//dragon = ImageIO.read(new File("images/Dragon.png"));
			//lizard = ImageIO.read(new File("images/Lizard.png"));
			//golem = ImageIO.read(new File("images/Golem.png"));
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		dialog = new JDialog();
		baronLabel = new JLabel("Not started yet");
		dragonLabel = new JLabel("Not started yet");
		lizardLabel = new JLabel("Not started yet");
		golemLabel = new JLabel("Not started yet");
		JPanel panel1 = new JPanel();
		panel1.add(baronPic);
		panel1.add(baronLabel);
		panel1.add(dragonPic);
		panel1.add(dragonLabel);
		panel1.add(lizardPic);
		panel1.add(lizardLabel);
		panel1.add(golemPic);
		panel1.add(golemLabel);
		panel1.setVisible(true);		
		panel1.setOpaque(false);		
		dialog.add(panel1);
		dialog.setUndecorated(true);
		dialog.setSize(new Dimension(128,600));
		dialog.setFocusable(true);
		dialog.setFocusableWindowState(true);
		dialog.setVisible(true);
		dialog.setLayout(null);
		dialog.addMouseListener(this);
		dialog.addMouseMotionListener(this);
		dialog.addKeyListener(this);
		dialog.setBackground(new Color(0,0,0,0));
		dialog.setLocation(0,-4);
		dialog.setAlwaysOnTop(true);
		
		timer.scheduleAtFixedRate(new TimerTask() {
	        public void run() {
	            if(baronCounter > 0) baronCounter --;
	            if(dragonCounter > 0) dragonCounter --;
	            if(lizardCounter > 0) lizardCounter --;
	            if(golemCounter > 0) golemCounter --;
	            setTextAll();
	        }
	    }, delay, period);
		
	}
	
	private void setTextAll() {
		baronLabel.setText(formatTime(baronCounter+""));
		dragonLabel.setText(formatTime(dragonCounter+""));
		lizardLabel.setText(formatTime(lizardCounter+""));
		golemLabel.setText(formatTime(golemCounter+""));
    }
    
    private String formatTime(String input2) {
    	int input = Integer.parseInt(input2);

    	double scale3600 = 1.0/3600;
    	double scale60 = 1.0/60;
    	int hh = (int) (input * scale3600);
    	int mm = (int) (input * scale60);
    	int ss = input - mm*60 - hh*3600;

    	DecimalFormat format = new DecimalFormat("00");
    	
    	return format.format(mm) + ":" + format.format(ss);
    }
    
    @Override
	public void mouseDragged(MouseEvent arg0) {
		dialog.setLocation(dialog.getLocation().x+(arg0.getX()-X), dialog.getLocation().y+(arg0.getY()-Y));
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
	}

	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
        X=e.getX();
        Y=e.getY();
	}

	@Override
	public void mouseReleased(MouseEvent e) {
	}

	@Override
	public void keyPressed(KeyEvent arg0) {		
		switch (arg0.getKeyCode()) {
		case 27:
			System.exit(1);
			break;
		case 97:
			baronCounter = baronTime;
			break;
		case 98:
			dragonCounter = dragonTime;
			break;
		case 99:
			lizardCounter = lizardTime;
			break;
		case 100:
			golemCounter = golemTime;
			break;
		case 101:
			System.out.println("Unbelegt - Numpad5");
			break;
		case 102:
			System.out.println("Unbelegt - Numpad6");
			break;
		}		
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}

	@Override
	public void keyTyped(KeyEvent e) {	
	}

}
```


----------



## Marco13 (30. Okt 2012)

Applikationsübergreifend ist das mit reinen Java-Bordmitteln nicht möglich. Es gibt Bibliotheken für sowas, Websuche nach "Java Global Key Hook" o.ä. liefert z.B. jnativehook - A library to provide global keyboard and mouse listeners for Java. - Google Project Hosting (NUR ein Suchergebnis, keine Empfehlung)


----------



## Spacerat (30. Okt 2012)

@Marco13: Möglich ist das mit Boardmitteln zumindest in GUI-Applikationen schon, aber unheimlich umständlich. Der steinige Weg führt über einen FocusListener, der jeder Component angehängt werden muss.

```
public class GlobalInputListener implements FocusListener {
  private KeyListener kl = new KeyAdapter() {
    // override desired methods
  }

  private MouseAdapter ml = new MouseAdapter() {
    // override desired methods
  }

  public void focusGained(FocusEvent e) {
    Component c = e.getOppositeComponent();
    c.removeKeyListener(kl);
    c.removeMouseMotionListener(ml):
    c.removeMouseWheelListener(ml):
    c.removeMouseListener(ml):
  }

  public void focusLost(FocusEvent e) {
    Component c = e.getOppositeComponent();
    c.addKeyListener(kl);
    c.addMouseMotionListener(ml):
    c.addMouseWheelListener(ml):
    c.addMouseListener(ml):
  }
}
```
[EDIT] Okay, wer lesen kann ist klar im Vorteil... Für das Vorhaben des TO reicht das natürlich nicht.[/EDIT]


----------

