I have installed a bar-code scanner from Datalogic, with the goal of reading the bar-code into a java textfield. However, when I scan the bar code in Swing, the resulting text is garbage. I cannot use this. On standalone java.awt.TextField is works fine, but when I integrate this into my code, it also produces garbage non-mappable characters.
Don't know if I'll need a specific driver for JAVA,
I have tried converting the string from UTF-8 to ISO-88... to no avail.
Been looking at this since 2 days in-vain.
Any help will be greatly appreciated.
Thanks
-innocent
try resetting the scanner to remove all spurios characters/codes that might have been set up; i.e. according to the reference guide the scanner will send by default the barcode id for gs1-128 codes as an escape sequence, which might cause some trouble for swing
download the product reference guide from http://www.datalogic.com/eng/quickscan-i-lite-qw2100-pd-163.html
scan the barcode to enter programming mode
go to the relevant section and scan the codes to remove all preambles and to remove the aim label for all codes
you can also try the different types of keyboard emulation and codepage.
There is a problem with KeyEvents coming from a barcode scanner using ALT + NumPad method. Java generates KeyTyped events with random outputs when ALT key is pressed. The problem exists in the current versions of Java 7 and Java 8 JRE (I have tested it with JRE 7u67 and JRE 8u20 on Windows 8, Windows 7 and Ubuntu 14).
My solution is to register a KeyEventDispatcher that blocks the KeyEvents when the ALT method is active:
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
new AltBugFixKeyEventDispatcher());
public class AltBugFixKeyEventDispatcher implements KeyEventDispatcher {
private int i = -1;
#Override
public boolean dispatchKeyEvent(KeyEvent ke) {
if (ke.isAltDown()) {
switch (ke.getID()) {
case KeyEvent.KEY_PRESSED:
if(ke.getKeyCode() == KeyEvent.VK_ALT){
i = 0;
}else if(Character.isDigit(ke.getKeyChar())){
i++;
}else{
i = -1;
}
break;
case KeyEvent.KEY_RELEASED:
break;
case KeyEvent.KEY_TYPED:
break;
}
if(i != -1){
return true;
}
}
return false;
}
}
My problem is explained in the following scenario
There are 2 JTextField objects. Let's give them variable names as jTextField1 and jTextField2. And the current focus owner is jTextField2. And the User and/or a Device is firing key inputs into the program. But according to the speed of each key being pressed and released the program should decide which text field the key char of that key input should be entered into. For an example, if the difference between KEY_PRESSED and KEY_RELEASED is less than or equal to 50 milliseconds, the Key Char should be typed into jTextField1 and never into jTextField2 but while the Focus is still owned by jTextField2 and unchanged. If the difference between the events are greater than 50 milliseconds, the text will be typed into its current Focus Owner which is jTextField2 (Or it may be any other object too according to what the User has the Focus at the moment.). So if there were 2 simultaneous activities happening, for an example a user is typing keys in a speed of greater than 50 milliseconds per key typing, and another device like a Barcode Scanner is firing Key Events in a speed less than 50 milliseconds, both of these inputs should be entered or typed into those different text fields separately according to their typing speeds while the focus owner is always at the object which the user is interacting with.
Here is the current code I have written which works well but with the problem that when keys are pressed in a speed less than 50 milliseconds per key, it sets at jTextField1 but it also gets typed at jTextField2.
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
millis = System.currentTimeMillis();
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
enter1 = true;
}
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
if ((System.currentTimeMillis() - millis) <= 10) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
enter2 = true;
} else {
barcodeStringBuilder.append(e.getKeyChar());
}
if (enter1 && enter2) {
compo = getFocusOwner();
jTextField1.setText(barcodePool.toString());
barcodeStringBuilder.setLength(0);
compo.requestFocus();
}
enter1 = false;
enter2 = false;
} else {
}
} else if (e.getID() == KeyEvent.KEY_TYPED) {
}
return false;
}
The previous attempt I made to accomplish this task was trying to handle the input of the two devices which are a Keyboard and a Barcode Scanner separately using the Java HID API which also was unsuccessful. You can find my question thread on it here. And then I made it into this option which so far seems to be a good option.
So, does anyone know an effective way to accomplish my task as I have described above?
Thank you! And your help is highly appreciated.
I would not give either JTextFields focus, would not use a KeyEventDispatcher, but would instead try to use Key Bindings, and then based on the timing, append the text into the appropriate text field. This would prevent focus issues sending the text to two text fields.
I am creating an application which helps solving problems of an accounting book. The application has 12 chapters. All chapters contains 15-20 problems. The problem is displayed in a JPanel containing various combo-boxes and formatted-text boxes. suppose i solved a problem half and want to save so that next time i can load that half solved question.
Saving should be done by clicking save from menubar. And loading by load from the menubar
All menubars and problem sheet are working but i am not able to save any thing. I was using jFilechooser...
Is their any way to do that?
How to save a panel with filled combo-boxes items and text-boxes. And is their any way to know that user has made any changes in any items so that on closing the problem i can again ask to save it first and then exit.
Thanks in advance.
Some of my codes:
private void openBtnMouseClicked(java.awt.event.MouseEvent evt) {
opening();
}
public void opening() {
JFileChooser chooser=new JFileChooser();
int choice=chooser.showOpenDialog(this);
javax.swing.JComboBox[] sourceALE = {aaCombo, baCombo, caCombo, daCombo, eaCombo, faCombo, gaCombo, haCombo, iaCombo, jaCombo, kaCombo,
alCombo, blCombo, clCombo, dlCombo, elCombo, flCombo, glCombo, hlCombo, ilCombo, jlCombo, klCombo,
aeCombo, beCombo, ceCombo, deCombo, eeCombo, feCombo, geCombo, heCombo, ieCombo, jeCombo, keCombo};
javax.swing.JTextField[] sourceP = {aeval1, beval, ceval, deval, eeval, feval, geval, heval, ieval, jeval, keval};
String [] comboboxes={"aaCombo", "baCombo", "caCombo", "daCombo", "eaCombo", "faCombo", "gaCombo", "haCombo", "iaCombo", "jaCombo", "kaCombo","alCombo", "blCombo", "clCombo", "dlCombo", "elCombo", "flCombo", "glCombo", "hlCombo", "ilCombo", "jlCombo","klCombo","aeCombo", "beCombo", "ceCombo", "deCombo", "eeCombo", "feCombo", "geCombo", "heCombo", "ieCombo", "jeCombo", "keCombo"};
if(choice==JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
try {
System.out.println("Hey");
Scanner scanner = new Scanner(new FileReader(file));
while ( scanner.hasNextLine() ){
Scanner scan = new Scanner(scanner.nextLine());
scan.useDelimiter("=");
if ( scan.hasNext() ){
String item=scan.next();
int value=scan.nextInt();
String color=scan.next();
for(int g=0;g<comboboxes.length;g++){
if(item.equals(comboboxes[g])) {
if(value<3)
sourceALE[g].setSelectedIndex(value);
if(color.equals("red"))
sourceALE[g].setForeground(red);
if(color.equals("green"))
sourceALE[g].setForeground(green);
if(color.equals("blah"))
sourceALE[g].setForeground(blah);
}
}
}
scan.close();
}
scanner.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(q1.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void opening() {
JFileChooser chooser=new JFileChooser();
int choice=chooser.showOpenDialog(this);
javax.swing.JComboBox[] sourceALE = {aaCombo, baCombo, caCombo, daCombo, eaCombo, faCombo, gaCombo, haCombo, iaCombo, jaCombo, kaCombo,
alCombo, blCombo, clCombo, dlCombo, elCombo, flCombo, glCombo, hlCombo, ilCombo, jlCombo, klCombo,
aeCombo, beCombo, ceCombo, deCombo, eeCombo, feCombo, geCombo, heCombo, ieCombo, jeCombo, keCombo};
javax.swing.JTextField[] sourceP = {aeval1, beval, ceval, deval, eeval, feval, geval, heval, ieval, jeval, keval};
String [] comboboxes={"aaCombo", "baCombo", "caCombo", "daCombo", "eaCombo", "faCombo", "gaCombo", "haCombo", "iaCombo", "jaCombo", "kaCombo","alCombo", "blCombo", "clCombo", "dlCombo", "elCombo", "flCombo", "glCombo", "hlCombo", "ilCombo", "jlCombo","klCombo","aeCombo", "beCombo", "ceCombo", "deCombo", "eeCombo", "feCombo", "geCombo", "heCombo", "ieCombo", "jeCombo", "keCombo"};
if(choice==JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
try {
System.out.println("Hey");
Scanner scanner = new Scanner(new FileReader(file));
while ( scanner.hasNextLine() ){
Scanner scan = new Scanner(scanner.nextLine());
scan.useDelimiter("=");
if ( scan.hasNext() ){
String item=scan.next();
int value=scan.nextInt();
String color=scan.next();
for(int g=0;g<comboboxes.length;g++){
if(item.equals(comboboxes[g])) {
if(value<3)
sourceALE[g].setSelectedIndex(value);
if(color.equals("red"))
sourceALE[g].setForeground(red);
if(color.equals("green"))
sourceALE[g].setForeground(green);
if(color.equals("blah"))
sourceALE[g].setForeground(blah);
}
}
}
scan.close();
}
scanner.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(q1.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("OUT");
}
}
1) It is good design to separate your data from the presentation. Are you doing this already? What I mean is you should be looking to store answers in an object outside of the jPanel class. (As 'Hovercraft Full Of Eels' suggested)
2) Consider making the data objects Serializable objects. If you're not planning on storing the data across a network or anything complicated/peculiar this should work out for you as it will facilitate save/load operations
3) Once you have your data separate from the GUI a check for changes becomes very easy. Assume that on any operation that takes you away from the page it "saves" its state. If the current state is different from the saved state then prompt the user to save (if it doesn't by default)
I have to wonder if you've created this program primarily as a NetBeans-generated GUI without first creating the non-GUI guts of the program. So first I have to ask, have you divided out your program logic from your GUI code a la MVC (model-view-controller) or one of its many variants? If not then this should be your first order of business, since in truth the saving and recovery of the data should have nothing to do with its GUI representation.
The key to solving your problem is going to be good object-oriented programming design. Consider for instance creating a non-GUI Question class that has several fields including a String question field, an ArrayList of possibleAnswers and a field String for the correctAnswer. Consider having an ArrayList of these Questions (ArrayList) for each chapter and a collection of the Chapters. Then you will need to figure out the best way for you to save the questions and the users answers. This may be via serialization, XML (JAXB?), or my recommendation: a database.
Only after you've figured out all of this should you worry about how to integrate a GUI around your non-GUI logic code which will be the GUI's "model".
Edit
Replies to your comments:
Sorry i havent provided enough info of my project. I m doing it in NETBEANS 7 GUI.I guess netbeans java programs are MVC
Sorry, no. If all you do is create a GUI with NetBeans you will be creating an unwieldy god-class. To have good MVC you must design it that way from the beginning. Again that means creating your program logic before creating the GUI which in your case includes creating multiple non-GUI classes as I've indicated above. There is no "automatic" MVC in NetBeans.
I may be wrong as i dont know much about MVC.
Yes, unfortunately you're wrong. Please read about it: Model-View-Controller. This will help you with your current and future design.
As of now i am able to save and retrieve. But i want your suggestion on that. It is quite hardcoded for each question.
And that should probably be fixed as you do not be hard-coding the questions. In fact the question text shouldn't even be part of the code but part of the data. Consider having the question in a comma-delimited text file or database.
i tried to answer 5 components and save it in notepad. And on loading it i am able to get all those components filled. Its working. But its quite hard coded and yes of course bad programming. But i have some time limitations so can you suggest anything similar to this logic. if by some function or method i could know all the components variable name present in my JPanel. like all the 15-20 combo-box and same no of text-box. I could make a function which can be common for all
Sorry, I wish I could, but I can't, not unless you first fix your design issues. Good luck!
Does anyone know how to go about creating field that would perform telephone number format masking, like here (___) ___-____:
http://www.smartclient.com/smartgwt/showcase/#form_masking
A better approach would be to let the user type whatever they want: "789-555-1234" or "(789) 555-1234" or "7895551234" and then when the field loses focus decide if what they typed can be a phone number. If so you can reformat it as "(789) 555-1234". There are several related questions about how to do that sort of thing with regular expressions; just be sure your regex accepts the format you're changing the user's input to, otherwise it will be really annoying to edit.
As an example, look what happens when you type ".5" into the left margin field in Microsoft's standard page setup dialog: when you tab out it changes it to "0.5".
UPDATE: Here's sample code in GWT to illustrate. For the sake of this example, assume there's an element called "phoneContainer" to put the text box in. GWT doesn't give you the full java.util.regex package, but it gives enough to do this:
private void reformatPhone(TextBox phoneField) {
String text = phoneField.getText();
text = text.replaceAll("\\D+", "");
if (text.length() == 10) {
phoneField.setText("(" + text.substring(0, 3) + ") " + text.substring(3, 6) + "-" + text.substring(6, 10));
}
}
public void onModuleLoad() {
final TextBox phoneField = new TextBox();
RootPanel.get("phoneContainer").add(phoneField);
phoneField.addBlurHandler(new BlurHandler(){
public void onBlur(BlurEvent event) {
reformatPhone(phoneField);
}
});
}
It looks like you'd want to create your own widget that extends the GWT input box and has a default value set to the mask you want. Then you handle the onKeypress event and update the field as needed (making sure to set the cursor position to the correct location).
I'm trying to learn something about GUI, using NetBeans6.8, starting with the GUI section in The java tutorial.
There is a simple exercise for a Celsius-Fahrenheit converter. I want that to have two TextFields, one for Celsius and one for Fahrenheit temperature; if the user types in the celsius text field he got the result "printed" in the fahrenheit text filed. and vice versa.
So, i put on both the textfields one KeyTyped event, here's the code:
private void celsiusTextKeyTyped(java.awt.event.KeyEvent evt) {
int cels = Integer.parseInt(celsiusText.getText());
int fahr = (int)(cels * 1.8 + 32);
fahrText.setText(fahr + "");
}
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt) {
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
It doesn't work. If i type something in a textfield i got this exception: java.lang.NumberFormatException: For input string: ""
The code that attach the listeners:
celsiusText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
celsiusTextKeyTyped(evt);
}
});
fahrText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
fahrTextKeyTyped(evt);
}
});
[However, i can't modify it, it's autogenerated.]
Method .getText() returns a string not a number, if that string contains non-numeric characters (i.e. a letter, a space, nothing at all) then parseInt will throw a NumberFormatException. Since your using KeyEvent, as soon as you press say "7", the event is fired before 7 is entered into the text box. Thus the text box still only contains "", which is where the error comes from. You may wish to also listen to the keyUp event instead.
You need to enclose your code in a try catch block.
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt)
{
try
{
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
catch(NumberFormatException ex)
{
//Error handling code here, i.e. informative message to the user
}
}
An alternative is you could filter out non-numbers on keydown event, see example here - http://www.javacoffeebreak.com/java107/java107.html (Creating a custom component - NumberTextField)
I suspect that what's happened is that you added these handlers with something like celsiusText.addKeyListener, yes?
The thing is, that'll give you not just the KEY_TYPED events you wanted, but also KEY_DOWN and KEY_UP. The KEY_DOWN event will happen before the text is really entered into the field, so your code firing on that will see the field as blank still. Trying to convert the empty string to a number gives you a format exception.
The easiest way to fix this is the try/catch construct other people have been posting.
You probably set action to keyDown, this mean that even occur before the key value is "added" to textbox, while You retrieve the value from it is still empty "".
There is a simple exercise for a
Celsius-Fahrenheit converter
That is a really old example. The better approach is to use a DocumentListener, not a KeyListener.