Tastatureingaben abfangen

Status
Nicht offen für weitere Antworten.

Kaladial

Bekanntes Mitglied
moin

ich hätte mal wieder nen problem:
ich hab nen kleines programm das folgendes machen soll:
mit meinem handscanner der über usb angeschlossen ist und der seinen gelesenen string einfach als tastatureingabe ausgibt
will ich ein feld mit dem inhalt des gelesenen strings füllen ...

so zur erklärung:
ich hab nen handscanner
wenn ich dort auf lesen drücke gibt der den barcode der er gelesen hat auf der tastatur aus.
dieses event will ich abfangen und in ein textfeld rein schreiben.

wie kann ich das machen ?
ich habs mit keylistener versucht aber irgendwie geht das net ...
also ich hab nen startknopf der den focus auf dieses textfeld setzt (setFocusable ist doch die richtige funktion dafür oder?)
und auf dem textfeld liegt wie gesagt der keylistener ... nur passiert da irgendwie gar nix...

wieso ???
thx für hilfe
Kala
 

Kaladial

Bekanntes Mitglied
ok problem gefunden ... ich darf das feld wo der listner liegt natürlich net enable false machen ...
 

Kaladial

Bekanntes Mitglied
ahja ich hab diesen globalen keylistner mal ausprobiert ...

2 fragen hab ich dazu:
wenn ich sage: hotkeyManager = GlobalHotkeyManager.getInstance();
wie kann ich dann auf die buchstaben was auch immer zugreifen ?
also wo seh ich was als eingabe kam ???

2.) wie kann ich den listner wieder deaktivieren ???
 

KrokoDiehl

Top Contributor
Alles was diese Implementierung tut, steht in der
Code:
dispathEvent()
-Methode. D.h. hier kannst du nach KeyEvent abfragen und dann das gleiche tun, wie z.B. in einem KeyListener. Wichtig ist nur, dass du alles andere an die Supermethode weiterleitest.
Wenn du ihn nicht haben willst, dann muss der Code aus dem static-Block weg, bzw. irgendwo ein Flag einbauen, dass die
Code:
dispathEvent()
alles direkt an die Supermethode weiterleitet und sonst nichts macht.
 

Kaladial

Bekanntes Mitglied
sorry aber : WAT ???

also folgendes: ich hab die class : GlobalHotkeyManager.java so übernommen wie sie in dem beispiel beschrieben ist...
zusaätzlich hab ich in meiner main-java-datei "public GlobalHotkeyManager hotkeyManager = null;" deklariert.

und in meinem jframe hab ich 2 jbutton und 1 textfeld...
wenn ich nun den 1. button drücke wird "hotkeyManager = GlobalHotkeyManager.getInstance();" ausgeführt... wenn ich nun in dem beispiel den debugmodus einschalte wird mir auf der komandozeile genau das ausgegeben was ich an tasten drück...

dieses möchte ich nun aber an meine main-datei übergeben und in dem textfeld ausgeben ...
und der 2. button soll dazu da sein den listner zu deaktivieren ...

ich baue eben mal nen kleines beispielprogramm um das zu verdeutlichen ... dauert aber noch 2 min :)
 

Kaladial

Bekanntes Mitglied
TestScanner.java:
Java:
package Handscanner;

import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Rectangle;
import javax.swing.JTextField;

public class TestScanner extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JButton jButtonAN = null;
	private JButton jButtonAus = null;
	private JTextField jTextFieldAusgabe = null;
	public GlobalHotkeyManager hotkeyManager = null;
	/**
	 * This is the default constructor
	 */
	public TestScanner() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		this.setTitle("JFrame");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(getJButtonAN(), null);
			jContentPane.add(getJButtonAus(), null);
			jContentPane.add(getJTextFieldAusgabe(), null);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jButtonAN	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonAN() {
		if (jButtonAN == null) {
			jButtonAN = new JButton();
			jButtonAN.setBounds(new Rectangle(18, 11, 69, 37));
			jButtonAN.setText("AN");
			jButtonAN.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					hotkeyManager = GlobalHotkeyManager.getInstance();
				}
			});
		}
		return jButtonAN;
	}

	/**
	 * This method initializes jButtonAus	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonAus() {
		if (jButtonAus == null) {
			jButtonAus = new JButton();
			jButtonAus.setBounds(new Rectangle(18, 58, 66, 40));
			jButtonAus.setText("Aus");
			jButtonAus.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
				}
			});
		}
		return jButtonAus;
	}

	/**
	 * This method initializes jTextFieldAusgabe	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextFieldAusgabe() {
		if (jTextFieldAusgabe == null) {
			jTextFieldAusgabe = new JTextField();
			jTextFieldAusgabe.setBounds(new Rectangle(139, 48, 139, 26));
		}
		return jTextFieldAusgabe;
	}

}

GlobalHotkeyManager.java
Java:
package Handscanner;

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

public class GlobalHotkeyManager extends EventQueue {
	private static final boolean DEBUG = true; // BUG? what's that? ;-))
	private static final GlobalHotkeyManager instance = new GlobalHotkeyManager();
	private final InputMap keyStrokes = new InputMap();
	private final ActionMap actions = new ActionMap();
	static {
    // here we register ourselves as a new link in the chain of
    // responsibility
		Toolkit.getDefaultToolkit().getSystemEventQueue().push(instance);
	}
	private GlobalHotkeyManager() {} // One is enough - singleton
	public static GlobalHotkeyManager getInstance() {
		return instance;
	}
	public InputMap getInputMap() {
		return keyStrokes;
	}
	public ActionMap getActionMap() {
		return actions;
	}
	protected void dispatchEvent(AWTEvent event) {
		if (event instanceof KeyEvent) {
			// KeyStroke.getKeyStrokeForEvent converts an ordinary KeyEvent
			// to a keystroke, as stored in the InputMap.  Keep in mind that
			// Numpad keystrokes are different to ordinary keys, i.e. if you
			// are listening to
			KeyStroke ks = KeyStroke.getKeyStrokeForEvent((KeyEvent)event);
			if (DEBUG) System.out.println("KeyStroke=" + ks);
				String actionKey = (String)keyStrokes.get(ks);
			if (actionKey != null) {
				if (DEBUG) System.out.println("ActionKey=" + actionKey);
					Action action = actions.get(actionKey);
				if (action != null && action.isEnabled()) {
					// I'm not sure about the parameters
					action.actionPerformed(new ActionEvent(event.getSource(), event.getID(), actionKey, ((KeyEvent)event).getModifiers()));
					return; // consume event
				}
			}
		}
		super.dispatchEvent(event); // let the next in chain handle event
	}
}
 

KrokoDiehl

Top Contributor
Das Problem ist folgender Teil im HKM (HotKeyManager):
Java:
static {
    // here we register ourselves as a new link in the chain of
    // responsibility
        Toolkit.getDefaultToolkit().getSystemEventQueue().push(instance);
    }
Der sorgt dafür, dass er immer geladen wird, egal ob du
Code:
 getInstance()
aufrufst, oder nicht. Zwei Lösungsansätze:
1. Das "static" wegmachen.
2. Den HKM á la lazy-creation umbauen, d.h. den obigen Code in den HKM-Konstruktor setzen und in
Code:
getInstance()
folgendes schreiben:
Java:
if (instance == null)
    instance = new GlobalHotkeyManager();
return instance;
(--> Singleton)

Grundsätzlich funktioniert der HKM wie ein KeyListener:
Java:
protected void dispatchEvent(AWTEvent event) {
        if (event instanceof KeyEvent) {
            // code vom KeyListener...
        }
        
        // normales Event-Handling
        super.dispatchEvent(event); 
}
D.h. an der o.g. muss du an dein Textfeld kommen und die Eingaben reinsetzen...
 

Kaladial

Bekanntes Mitglied
kannst du mir das in meinen code einbauen ???
weil irgendwie bekomm ich das net hin ...

Java:
public class Singleton {
  private static Singleton instance;
  
  private Singleton() {
  }
        
  public static synchronized Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
  }
}

^^ auf die art und weise hab ich das umgebaut ... nu geht nix mehr :(
 
Zuletzt bearbeitet:

KrokoDiehl

Top Contributor
Java:
public class GlobalKeyListener extends EventQueue
{
    private static GlobalKeyListenern instance = null;
    
    public static GlobalKeyListener getInstance()
    {
        if (instance == null)
            instance = new GlobalKeyListener();
        return instance;
    }

    private GlobalKeyListener()
    {
        Toolkit.getDefaultToolkit().getSystemEventQueue().push(this);
    }

    public void dispatchEvent(AWTEvent event)
    {   
        if (event instanceof KeyEvent)
        {
            KeyEvent kEvent = (KeyEvent)event;
            //hier was tun...
        }             

        super.dispatchEvent(event);
    }
}

Hier, das wäre der GlobalKeyManager als Singleton. Wobei es nicht nötig wäre... aber egal, will dich nicht weiter verwirren ;)
 

Kaladial

Bekanntes Mitglied
ok so das wäre jetzt die möglichkeit das es wieder funktioniert ...
jetzt sind noch 2 sachen offen:

1.) wie deaktiviere ich das nun wieder?
bin mir nicht sicher aber einfach den aufruf:
Java:
hotkeyManager = GlobalHotkeyManager.getInstance();
wieder auf null setzten hat nix gebracht ...

2.) wie schreib ich nun aus dem event raus in mein textfeld?
weil dierekt auf das textfeld zugreifen hat net geklappt auch nachdem ich es public gemacht hab ...
 

KrokoDiehl

Top Contributor
Zuerst einmal:
Sobald ein GlobalKeyListener erstellt wird, setzt er sich in die SystemEventQueue (vgl. Konstruktor). Habe spontan keine Methode gefunden, die ihn da wieder rausholt. Aber wenn du ihn nicht drin haben willst, dann brauchst du auch kein
Code:
getInstance()
aufrufen...

Dann:
Wenn du von Klasse A auf Klasse B (A= GlobalKeyListener, B= Textfeld) zugreifen willst, gibt es ca. 100 Möglichkeiten. Die wohl einfachste ist, dass du A eine Referenz von B gibst, á la
Java:
public class A
{
    protected B meinB = null;

    public void setB(B neuesB)
    {
        meinB = neuesB;
    }
}
So könntest du dem GKeyListener eine Referenz vom Textfeld übergeben, in das er dann die KeyEvent reinschreibt.
Aber wie oben schon gesagt: Du erwähntest, dass dein Programm auch ohne geht, warum also die Mühe...
 

Kaladial

Bekanntes Mitglied
die variante mit dem globalen listner gefällt mir besser, da ich mit meiner anderen variante probleme mit sonderzeichen hab...

also ich hab ja einen barcodescanner der dmax codes liest ..
der dmax code wird aus bestimmten komponenten zusammen gesetzt unter andern mit einer seriennummer die zum abschluss das zeichen /f oder ascii 29 enthält ... meine bisherige variante hat damit n bissi probleme die der globallistner nicht hatte ... daher wollte ich gern diesen benutzen ...

und hmmm das man den nicht deaktivieren kann ist n bissi doof ...
hat da vielleicht wer anders noch ne idee?
 

Kaladial

Bekanntes Mitglied
Zuerst einmal:
Sobald ein GlobalKeyListener erstellt wird, setzt er sich in die SystemEventQueue (vgl. Konstruktor). Habe spontan keine Methode gefunden, die ihn da wieder rausholt. Aber wenn du ihn nicht drin haben willst, dann brauchst du auch kein
Code:
getInstance()
aufrufen...

Dann:
Wenn du von Klasse A auf Klasse B (A= GlobalKeyListener, B= Textfeld) zugreifen willst, gibt es ca. 100 Möglichkeiten. Die wohl einfachste ist, dass du A eine Referenz von B gibst, á la
Java:
public class A
{
    protected B meinB = null;

    public void setB(B neuesB)
    {
        meinB = neuesB;
    }
}
So könntest du dem GKeyListener eine Referenz vom Textfeld übergeben, in das er dann die KeyEvent reinschreibt.
Aber wie oben schon gesagt: Du erwähntest, dass dein Programm auch ohne geht, warum also die Mühe...


hmmm das versteh ich noch nicht so ganz ...
ich hab in meinem testprogramm:
TestScanner ein textfeld das jTextFieldAusgabe heist...

laut deiner beschreibung müsste mein code so ausehn:

Java:
public class GlobalHotkeyManager
{
    protected jTextFieldAusgabe meinB = null;

    public void setB(jTextFieldAusgabe neuesB)
    {
        meinB = neuesB;
    }
}

^^ und das geht net ...
ich will ja auch eigentlich nur auf settext von jTextFieldAusgabe zugreifen ...
 

Kaladial

Bekanntes Mitglied
jo das mein ich ja ... wie bekomm ich aber die referenz auf mein JTextField??

also ich hätte sowas erwartet:

JTextField meinTF = jTextFieldAusgabe;

oder

JTextField meinTF = TestScanner.jTextFieldAusgabe;

um dann in der dispatchEvent - Funktion mit meinTF.setText();
den inhalt zu füllen... aber das geht nicht ... ich bekomm mit TestScanner. -> keine anzeige von jTextFieldAusgabe
und wenn ich sag: TestScanner.this.jTextFieldAusgabe bekomm ich fehlermeldungen ...
 
Zuletzt bearbeitet:

KrokoDiehl

Top Contributor
Java:
public class GlobalKeyListener extends EventQueue
{
    private static GlobalKeyListenern instance = null;
    
    public static GlobalKeyListener getInstance()
    {
        if (instance == null)
            instance = new GlobalKeyListener();
        return instance;
    }


    protected JTextField inputField = null;
    protected boolean disabled = false;

    private GlobalKeyListener()
    {
        Toolkit.getDefaultToolkit().getSystemEventQueue().push(this);
    }
 
    public void setTextfield(JTextField field)
    {
        inputField = field;
    }
    
    public void disable()
    {
        disabled = true;
    }

    public void enable()
    {
        disabled = false;
    }

    public void removeListener()
    {
        // s. Ebenius' Post
        this.pop();
    }

    @Override
    public void dispatchEvent(AWTEvent event)
    {   
        if (event instanceof KeyEvent && ! disabled)
        {
            KeyEvent kEvent = (KeyEvent)event;
            if (inputField != null)
                inputField.setText( inputField.getText() + kEvent.getKeyChar() );
        }             
 
        super.dispatchEvent(event);
    }
}

Dann kannst du ihn von außen wie folgt behandeln:
Java:
GlobalKeyListener gkl = GlobalKeyListener.getInstance();
gkl.setTextfield(jTextFieldAusgabe);
...und alles sollte tun, ohne es getestet zu haben ;)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
pinerski Swing JList Tastatureingaben abfangen AWT, Swing, JavaFX & SWT 2
K Swing Keine Reaktion auf Tastatureingaben bei mehreren Buttons??? AWT, Swing, JavaFX & SWT 4
M Zeitkritisches auslesen von Tastatureingaben AWT, Swing, JavaFX & SWT 6
T Tastatureingaben in jTextFields AWT, Swing, JavaFX & SWT 8
D Swing Tastatureingaben anzeigen AWT, Swing, JavaFX & SWT 6
R Programmweite Shortcuts, Tastatureingaben AWT, Swing, JavaFX & SWT 11
T ScrollEvent richtig(er) abfangen? AWT, Swing, JavaFX & SWT 0
A JOptionPane OK ohne Eingabe abfangen AWT, Swing, JavaFX & SWT 10
Neumi5694 Swing JList - Klick abfangen AWT, Swing, JavaFX & SWT 3
D Swing Events vom JLayer abfangen AWT, Swing, JavaFX & SWT 2
E Outlook Email Senden-Button abfangen AWT, Swing, JavaFX & SWT 5
C Programm für 5 sekunden anhalten und actionevent abfangen AWT, Swing, JavaFX & SWT 18
T Swing JTextPane Tastatureingabe abfangen AWT, Swing, JavaFX & SWT 4
M JFileChooser Abfangen des DateiTypen möglich?? AWT, Swing, JavaFX & SWT 5
S Swing JTable - Editierung von Zellen abfangen AWT, Swing, JavaFX & SWT 3
P Action Event abfangen etwas anders? AWT, Swing, JavaFX & SWT 2
M JOptionPane.showInputDialog abbrechen abfangen? AWT, Swing, JavaFX & SWT 2
P Swing Tastaturereignisse auf gesamten Frame Abfangen AWT, Swing, JavaFX & SWT 13
sylo STRG + TAB KeyEvent abfangen AWT, Swing, JavaFX & SWT 6
M JTextField Tastendruck Abfangen AWT, Swing, JavaFX & SWT 3
H warum kann ich das focus event nicht abfangen ? AWT, Swing, JavaFX & SWT 5
C JTable: Alle selektierten Zellen abfangen AWT, Swing, JavaFX & SWT 13
J JPanel.addKeyListener() - JEDEN Tastendruck im Panel abfangen AWT, Swing, JavaFX & SWT 2
J AWT Abfangen der Rohdaten die PrinterJob zum Drucker sendet AWT, Swing, JavaFX & SWT 2
P Leere Textfelder abfangen AWT, Swing, JavaFX & SWT 4
F MouseEvent bei PopupMenu abfangen AWT, Swing, JavaFX & SWT 2
H Ich kann MouseDragged nicht abfangen AWT, Swing, JavaFX & SWT 3
G Swing Fortschrittsbalken im Fenster: Menü deaktivieren / abfangen? AWT, Swing, JavaFX & SWT 27
M Doppelklick auf Component abfangen AWT, Swing, JavaFX & SWT 5
E Swing Wechsel in JCheckBox abfangen AWT, Swing, JavaFX & SWT 10
R ALt+CTRL down, wie abfangen? AWT, Swing, JavaFX & SWT 2
R Checkboxen - Event mit Controller abfangen AWT, Swing, JavaFX & SWT 7
K Alle Events abfangen mit GlassPane AWT, Swing, JavaFX & SWT 7
E MouseEvent von Kindelementen abfangen AWT, Swing, JavaFX & SWT 2
R Texteingabe abfangen AWT, Swing, JavaFX & SWT 5
P SWT: KeyEvents abfangen, wenn Programm minimiert ist? AWT, Swing, JavaFX & SWT 5
K JTable und auf den Tabellenkopf-Click-Event abfangen AWT, Swing, JavaFX & SWT 2
M Globale Events in Windows abfangen AWT, Swing, JavaFX & SWT 2
S Events abfangen, nicht durchlassen AWT, Swing, JavaFX & SWT 2
G Zwischenablage abfangen AWT, Swing, JavaFX & SWT 4
M JTable alte Daten vor Änderung abfangen AWT, Swing, JavaFX & SWT 11
D Wie Taste "ENTER" bei PlainDocument abfangen? AWT, Swing, JavaFX & SWT 2
P SWT Fenster schließen abfangen AWT, Swing, JavaFX & SWT 4
S Minimieren abfangen AWT, Swing, JavaFX & SWT 2
A Tasten abfangen AWT, Swing, JavaFX & SWT 9
M Tastendruck abfangen AWT, Swing, JavaFX & SWT 8
S "Enter" in JTextField abfangen AWT, Swing, JavaFX & SWT 7
B Tastatureingabe in JComboBox abfangen. AWT, Swing, JavaFX & SWT 6
K JFrame setDefaultCloseOperation: Wie abfangen? AWT, Swing, JavaFX & SWT 2
G Ein klick auf JPanel abfangen und verarbeiten? AWT, Swing, JavaFX & SWT 3
J Keyevents abfangen in einer JTable AWT, Swing, JavaFX & SWT 2
F Habe Problem mit dem Abfangen einer Exception AWT, Swing, JavaFX & SWT 10
S Events bei 2 gleichen Jtree abfangen AWT, Swing, JavaFX & SWT 3
M Ereignis der JList abfangen AWT, Swing, JavaFX & SWT 2
O Exception abfangen AWT, Swing, JavaFX & SWT 19
K MouseEvents vor den Components abfangen? AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen


Oben