I have a JComboBox that is set to editable and has a keylistener attached. The input comes from a scan gun. What I am trying to do is if there are more than one item in the JComboBox, I need to scan a barcode that represents the # sign and it will scroll to the next item. The problem is that when I scan the # sign barcode, it scrolls which is good, but then it places the # sign at the end of the item text in the JComboBox. So say the item text was "1234", it ends up being "1234#". How do I keep the # sign from showing up? In VB I would just set the keycode = 0. I tried to do a e.setKeyCode(0); but didn't work.

private JComboBox getFromComboBox() {
  if (fromComboBox == null) {
    fromComboBox = new JComboBox();
    fromComboBox.setEditable(true);
    fromComboBox.setBackground(Color.white);
    fromComboBox.setFont(new Font("Arial", Font.BOLD, 52));
    fromComboBox.setModel(new DefaultComboBoxModel(new Object[] { "" }));
    fromComboBox.setDoubleBuffered(false);
    fromComboBox.setBorder(null);
    fromComboBox.getEditor().getEditorComponent().
    addKeyListener(new KeyAdapter() {
	public void keyPressed(KeyEvent event) {
	   fromComboBoxKeyKeyPressed(event);
	}
    });
    fromComboBox.addFocusListener(new FocusAdapter() {
	
	public void focusGained(FocusEvent event) {
	   fromComboBoxFocusFocusGained(event);
	}
	 
        public void focusLost(FocusEvent event) {
	  fromComboBoxFocusFocusLost(event);
        }
    });
  }
  return fromComboBox;
}
private void fromComboBoxKeyKeyPressed(KeyEvent e) {
   int num = fromComboBox.getItemCount();
		
   if (e.getKeyCode() == 10) {
      //enter key 
      if (WarehouseTracer.bScroll.equals(true)) {
	 fromComboBox.requestFocus();
	 WarehouseTracer.bScroll = false;
      }else {
	 FromInput();
      }
    }else if ((e.getKeyCode() == 51) && (e.isShiftDown())){
      //use # to scroll through From dropdown
      WarehouseTracer.bScroll = true;
      if (fromComboBox.getItemAt(num - 1).equals(fromComboBox.getSelectedItem())) {
	fromComboBox.setSelectedIndex(0);
      }else{
	e.setKeyCode(0);
	fromComboBox.setSelectedIndex(fromComboBox.getSelectedIndex() + 1);
      }
    }else if (e.getKeyCode() == 62) {
       toText.requestFocus();
   }
}

Thanks!

Recommended Answers

All 8 Replies

Comment on using hardcoded literals in your code for testing keycodes.
Why not use the self documenting VK_ symbols
Or the literal '3' where you have the 51.

Have you tried the consume() method?

I didn't know about the VK_symbols. I will look into those, thanks.

I will research this consume method also.

OK, I found what I could about the consume() method and tried it in a couple places. I added it as the first line of code after:
}else if (e.getKeyCode() == KeyEvent.VK_NUMBER_SIGN){

No luck there.

And I added it before the line:
fromComboBox.setSelectedIndex(fromComboBox.getSelectedIndex() + 1);

No luck there either.

I found some successful code on a jtextfield. I was wondering if the jcombobox couldn't handle this specifically. I know I had to use this code to select the text in the combo:
JTextField field = (JTextField)fromComboBox.getEditor().getEditorComponent();

Do I need to do something like this and if so, any pointers?

Thanks.

Can you make a small program that will compile, execute and demonstrate the problem?

Small program that will demonstrate the problem. I use a scan gun to scroll through the combobox.

package testb;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;

//VS4E -- DO NOT REMOVE THIS LINE!
public class TestB extends JFrame {

	private static final long serialVersionUID = 1L;
	private JComboBox fromComboBox;
	private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";

	public TestB() {
		initComponents();
	}

	private void initComponents() {
		setLayout(new GroupLayout());
		add(getJComboBox0(), new Constraints(new Leading(84, 148, 10, 10), new Leading(138, 10, 10)));
		setSize(320, 240);
	}

	private JComboBox getJComboBox0() {
		if (fromComboBox == null) {
			fromComboBox = new JComboBox();
			fromComboBox.setEditable(true);
			fromComboBox.setModel(new DefaultComboBoxModel(new Object[] { "" }));
			fromComboBox.setDoubleBuffered(false);
			fromComboBox.setBorder(null);
			fromComboBox.addItem("oranges");
			fromComboBox.addItem("lemons");
			fromComboBox.addItem("limes");
			
			fromComboBox.getEditor().getEditorComponent().
			addKeyListener(new KeyAdapter() {
	
				public void keyPressed(KeyEvent event) {
					fromComboBoxKeyKeyPressed(event);
				}
			});
		}
		return fromComboBox;
	}

	private static void installLnF() {
		try {
			String lnfClassname = PREFERRED_LOOK_AND_FEEL;
			if (lnfClassname == null)
				lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
			UIManager.setLookAndFeel(lnfClassname);
		} catch (Exception e) {
			System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
					+ " on this platform:" + e.getMessage());
		}
	}

	/**
	 * Main entry of the class.
	 * Note: This class is only created so that you can easily preview the result at runtime.
	 * It is not expected to be managed by the designer.
	 * You can modify it as you like.
	 */
	public static void main(String[] args) {
		installLnF();
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				TestB frame = new TestB();
				frame.setDefaultCloseOperation(TestB.EXIT_ON_CLOSE);
				frame.setTitle("TestB");
				frame.getContentPane().setPreferredSize(frame.getSize());
				frame.pack();
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
			}
		});
	}
	
	//Here is the problem area.  When a user Scans a barcode representing a # sign
	//while focus is on the fromComboBox, this code is used to scroll through the list.
	//It scrolls through the list fine, but it also adds the # sign to the end of the text
	//that is in the fromComboBox.  So if the value is set to "oranges" and the user scans
	//the # sign it will move to lemons, but show up as "lemons#".
	private void fromComboBoxKeyKeyPressed(KeyEvent e) {
		int num = fromComboBox.getItemCount();
		
		if ((e.getKeyCode() == 51) && (e.isShiftDown())){
			//use # to scroll through From dropdown
			if (fromComboBox.getItemAt(num - 1).equals(fromComboBox.getSelectedItem())) {
				fromComboBox.setSelectedIndex(0);
			}else{
				fromComboBox.setSelectedIndex(fromComboBox.getSelectedIndex() + 1);
			}
		}
	}

}

I think its a Swing GUI problem. I changed the code to allow a '0' to also trigger your code and saw the '0' concatentated on the end of the selected item.
Move the selection code to a thread using invokeLater and it doesn't

Here's my test code:

private void fromComboBoxKeyKeyPressed(KeyEvent e, String id) {
		final int num = fromComboBox.getItemCount();
		System.out.println(id + "kP=" + e); // + "\n  <<>>keyCode=" + e.getKeyCode() + ", keyChar=" + e.getKeyChar());

		if ((e.getKeyCode() == '3') && (e.isShiftDown()) || (e.getKeyCode() == '0')){
			//use # to scroll through From dropdown
                    System.out.println(">>>>kP.keyChar=" + e.getKeyChar());
                    // NOTE THE last char entered is concat on the end of the selected item!!!!
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
      			if (fromComboBox.getItemAt(num - 1).equals(fromComboBox.getSelectedItem())) {
      				fromComboBox.setSelectedIndex(0);
      			}else{
      				fromComboBox.setSelectedIndex(fromComboBox.getSelectedIndex() + 1);
      			}
            }
         });
		}else{
        System.out.println("ignoring");
      }
	}

Sorry about the tabbing. My tab spacing is different from the forums.

Switching to use keyReleased() instead of keyPressed() and consuming the key event will fix it.

addKeyListener(new KeyAdapter() {

        public void keyReleased(KeyEvent event) {
                fromComboBoxKeyKeyPressed(event);
        }
});
private void fromComboBoxKeyKeyPressed(KeyEvent e) {
        int num = fromComboBox.getItemCount();

        if ((e.getKeyCode() == 51) && (e.isShiftDown())){
                //use # to scroll through From dropdown
                if (fromComboBox.getItemAt(num - 1).equals(fromComboBox.getSelectedItem())) {
                        fromComboBox.setSelectedIndex(0);
                }else{
                        fromComboBox.setSelectedIndex(fromComboBox.getSelectedIndex() + 1);
                }
                // consume here so nothing else processes it
                e.consume();
        }
}

You can see that the '#' is still being appended temporarily by the editor, but the selection on release is setting the selection to the original item, so the appended text is replaced.

I used the solution provided by NormR1 and it worked pefectly. Much appreciated.

Ezzaral, thanks also for your suggestion. I will check it out as well.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.