Kyslik
Kyslik

Reputation: 8385

Java swt KeyListener "solution" barcode reading

I found some good Q/A here on my problem but couldn't find the right one.

I have a barcode reader that reads barcode and sends scanned code as keyboard input. It is alright I can catch input easily

browser.addKeyListener(new KeyAdapter() {   
    @Override public void keyPressed(KeyEvent e) {
        if(e.keyCode >=48 && e.keyCode <=57) {
            System.out.println("number caught");
        } 
    }
});

But I will have more inputs in my application so I need to know if it is send by barcode reader or by keyboard. I think it can be achieved by adding some timer in code that verifies how long is some "sequence" reading.

I just can not figure it out, (I mean logic behind it), I am missing piece of logic.

  1. User is typing some info, (alpha numerical)
  2. user desides to use barcode reader to read barcode

I tried timer e.g if(System.currentTimeMillis() - lastPressProcessed ??? 500) { after keyListener is triggered but I think I am missing something.

sidenote: USB barcode reads code fast so keystrokes are emulated really fast est whole barcode is written in about 1 second + carry /r/n (also enter is pressed).

sidenote2: barcodes are going to be different in length so I can not read just some length in short time and decide wether it is user input or barcode input (max numbers read 13 + enter).

sidenote3: I have no input field for barcode I am trying to achieve running it on "background".

I am seeking logic/pseudocode suggestions on topic.

related topics that are really close to mine are here, and here

Thank you.

edit

After deep tought I found out the solution I'll keep this Q here just for another users that might find this usable.

solution --moved to answer + edited

Upvotes: 2

Views: 3575

Answers (2)

JHead
JHead

Reputation: 426

Here you can download my solution:

http://jhead.hu/resource/java/general/BarcodeReader.java

The following code sample shows you, how to use it. When a new barcode is identified, an ActionEvent is generated and you can get the barcode via the getActionCommand() method. If the panel is not active you can send the characters further to the focus manager.

The only problem is that my barcode scanner sends the characters too fast so the character bits are sometimes mixed. I've got no better solution yet.

public class PanelWithBarcodeReading extends javax.swing.JPanel implements ActionListener {

    private BarcodeReader barcodeReader = new BarcodeReader();

    public PanelWithBarcodeReading() {
        initComponents();
        barcodeReader.addActionListener(this);
        barcodeReader.setParent(this);
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(barcodeReader);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (SwingUtilities.getWindowAncestor(this).isActive()) {
            System.out.println("BARCODE='" + e.getActionCommand() + "'");
        } else {
            barcodeReader.dispatchLastBarcodeAsKeyEvents();
        }
    }

    ...
}

Upvotes: 1

Kyslik
Kyslik

Reputation: 8385

This code coveres everything I wanted to achieve, it reads just numbers (actualy numbers that are under F keys, not numbers that are on numpad, I had problem with it because scanner is keyboard dependant so I made function signsToNumbers() that converts signs !@#$%^&*() to numbers 1234567890. I may change this function because every key on keyboard has its own unique identifier + modifier, it seems that scanner sends also SHIFT modifier to the application but that is not as problem as it seems I'll just match e.keyCode.

The code below works as:

  1. waits for number input otherwise does nothing
  2. if 1st number is inserted it is looping in if condition until either 200ms is reached or '\r\n` is received
  3. sends data to server via URL

code

@Override public void keyPressed(KeyEvent e) {
    if (timer == true && System.currentTimeMillis() - lastTimer < 200) {
      if(e.keyCode >=48 && e.keyCode <=57) { //number pressed
          lastTimer = System.currentTimeMillis();
          myString = myString + Character.toString(e.character);
        }
        if(e.keyCode == SWT.CR) {
          myString = signsToNumbers(myString);
          newUrl = browser.getUrl()+ "/newcode/" + myString;
          browser.setUrl(newUrl);
          text.setText(newUrl);
          System.out.println(myString);
          System.out.println("barcode read");
          myString = "";
          timer = false;
          lastTimer = 0;
        }
    }else{
        if(e.keyCode >=48 && e.keyCode <=57) {
          lastTimer = System.currentTimeMillis();
          timer = true;
          myString = Character.toString(e.character);
        }
        myString = "";
        lastTimer = 0;
    }        
  }
});

Upvotes: 1

Related Questions