i've done an application with two JTextField with the autocomplete feature the application works fine but On clicking the Tab Button while the mouse pointer is on the first TextField the Mouse focus is not going into the second Textfield but gets the focus on the second time. i.e for passing the focus we have press the Tab button twice

Can anyone tell me wat's the reason and the solution for this problem

My code is given below

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.text.Collator;
import java.util.*;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class AutoCompleteExample extends javax.swing.JFrame {
    public AutoCompleteExample() {
        initComponents();
         List<Country> countries = new ArrayList<Country>();

        Locale[] locales = Locale.getAvailableLocales();
        for (Locale locale : locales) {
        String iso = locale.getISO3Country();
        String code = locale.getCountry();

        String name = locale.getDisplayCountry();

        if (!"".equals(iso) && !"".equals(code) && !"".equals(name)) {
            countries.add(new Country(iso, code, name));
        }
        }

        Collections.sort(countries, new CountryComparator());
        java.util.Set<String> item = new java.util.TreeSet<String>();
        for(Country cn:countries){
            item.add(""+cn);
        }
        ArrayList<String> items = new ArrayList<String>(item);
        setupAutoComplete(country,code, items);
        country.setColumns(30);   
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jDesktopPane1 = new javax.swing.JDesktopPane();
        jLabel1 = new javax.swing.JLabel();
        country = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        code = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jDesktopPane1.setBackground(javax.swing.UIManager.getDefaults().getColor("Button.background"));

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel1.setText("Country Name");
        jLabel1.setBounds(0, 10, 80, 20);
        jDesktopPane1.add(jLabel1, javax.swing.JLayeredPane.DEFAULT_LAYER);

        country.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                countryFocusLost(evt);
            }
        });
        country.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                countryKeyReleased(evt);
            }
        });
        country.setBounds(90, 10, 140, 20);
        jDesktopPane1.add(country, javax.swing.JLayeredPane.DEFAULT_LAYER);

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel2.setText("Code");
        jLabel2.setBounds(235, 10, 50, 20);
        jDesktopPane1.add(jLabel2, javax.swing.JLayeredPane.DEFAULT_LAYER);
        code.setBounds(300, 10, 160, 20);
        jDesktopPane1.add(code, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jDesktopPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 473, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jDesktopPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 43, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>

    private void countryFocusLost(java.awt.event.FocusEvent evt) {
        // TODO add your handling code here:
    }

    private void countryKeyReleased(java.awt.event.KeyEvent evt) {

    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new AutoCompleteExample().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify
    public static javax.swing.JTextField code;
    public static javax.swing.JTextField country;
    private javax.swing.JDesktopPane jDesktopPane1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    // End of variables declaration



 private static boolean isAdjusting(JComboBox cbInput) {
        if (cbInput.getClientProperty("is_adjusting") instanceof Boolean) {
            return (Boolean) cbInput.getClientProperty("is_adjusting");
        }
        return false;
    }

    private static void setAdjusting(JComboBox cbInput, boolean adjusting) {
        cbInput.putClientProperty("is_adjusting", adjusting);
    }

    public static void setupAutoComplete(final JTextField txtInput,final JTextField txtInput2, final ArrayList<String> items) {
        final DefaultComboBoxModel model = new DefaultComboBoxModel();
        final JComboBox cbInput = new JComboBox(model) {
            public Dimension getPreferredSize() {
                return new Dimension(super.getPreferredSize().width, 0);
            }
        };
        setAdjusting(cbInput, false);
        for (Object item : items) {
            model.addElement(item);
        }
        cbInput.setSelectedItem(null);
        cbInput.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!isAdjusting(cbInput)) {
                    if (cbInput.getSelectedItem() != null) {
                        txtInput.setText(cbInput.getSelectedItem().toString());
                        txtInput2.setText(datas.get(cbInput.getSelectedItem().toString())+"");
                    }
                }
            }
        });

        txtInput.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                setAdjusting(cbInput, true);
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    if (cbInput.isPopupVisible()) {
                        e.setKeyCode(KeyEvent.VK_ENTER);
                    }
                }
                if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) {
                    e.setSource(cbInput);
                    cbInput.dispatchEvent(e);
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtInput.setText(cbInput.getSelectedItem().toString());
                        // System.out.println("SEEEEE:"+datas.get(cbInput.getSelectedItem().toString()));
                        txtInput2.setText(datas.get(cbInput.getSelectedItem().toString())+"");
                        cbInput.setPopupVisible(false);
                    }
                }
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    cbInput.setPopupVisible(false);
                }
                setAdjusting(cbInput, false);
            }
            @Override
             public void keyReleased(KeyEvent e)
             {
                setAdjusting(cbInput, true);
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    if (cbInput.isPopupVisible()) {
                        e.setKeyCode(KeyEvent.VK_ENTER);
                    }
                }
                if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) {
                    e.setSource(cbInput);
                    cbInput.dispatchEvent(e);
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtInput.setText(cbInput.getSelectedItem().toString());
                        // System.out.println("SEEEEE:"+datas.get(cbInput.getSelectedItem().toString()));
                        txtInput2.setText(datas.get(cbInput.getSelectedItem().toString())+"");
                        cbInput.setPopupVisible(false);
                    }
                }
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    cbInput.setPopupVisible(false);
                }
                setAdjusting(cbInput, false);
             }
        });


        txtInput.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) {

            }
            @Override
            public void focusLost(FocusEvent e) {
            try{     setAdjusting(cbInput, true);
                 e.setSource(cbInput);
                 cbInput.dispatchEvent(e);
                 txtInput.setText(cbInput.getSelectedItem().toString());
                       // System.out.println("SEEEEE:"+datas.get(cbInput.getSelectedItem().toString()));
                 txtInput2.setText(datas.get(cbInput.getSelectedItem().toString())+"");
                 cbInput.setPopupVisible(false); 
                 setAdjusting(cbInput, false);
            }catch(Exception s){country.setText("");code.setText("");
            }
              }
            });


        txtInput.getDocument().addDocumentListener(new DocumentListener() {
            public void insertUpdate(DocumentEvent e) {
                updateList();
            }

            public void removeUpdate(DocumentEvent e) {
                updateList();
            }

            public void changedUpdate(DocumentEvent e) {
                updateList();
            }

            private void updateList() {
                setAdjusting(cbInput, true);
                model.removeAllElements();
                String input = txtInput.getText();
                if (!input.isEmpty()) {
                    for (Object item : items) {
                        if ((item+"").toLowerCase().startsWith(input.toLowerCase())) {
                            model.addElement(item);
                        }
                    }
                }
                cbInput.setPopupVisible(model.getSize() > 0);
                setAdjusting(cbInput, false);
            }
        });
        txtInput.setLayout(new BorderLayout());
        txtInput.add(cbInput, BorderLayout.SOUTH);
    }
    public static HashMap datas=new HashMap();;
}

////////////////////////////////////////////////////class JTextFieldLimits for limiting texfield strength/////////////////////////////////////////

class JTextFieldLimits extends PlainDocument {
  private int limit;
  JTextFieldLimits(int limit) {
   super();
   this.limit = limit;
   }

    @Override
  public void insertString( int offset, String  str, AttributeSet attr ) throws BadLocationException {
    if (str == null) return;

    if ((getLength() + str.length()) <= limit) {
      super.insertString(offset, str, attr);
    }
  }
}

////////////////////////////////////////////////////class Country for getting names/////////////////////////////////////////


class Country {
  private String iso;

  private String code;

  public String name;

  Country(String iso, String code, String name) {
    this.iso = iso;
    this.code = code;
    this.name = name;
      AutoCompleteExample.datas.put(name, code);
  }

    @Override
  public String toString() {

    return  name;
  }

  public String getName() {
    return  code;
  }



}

class CountryComparator implements Comparator<Country> {
  private Comparator comparator;

  CountryComparator() {
    comparator = Collator.getInstance();
  }

    @Override
  public int compare(Country o1, Country o2) {
    return comparator.compare(o1.name, o2.name);
  }
}

Recommended Answers

All 4 Replies

The issue you are having is from the order you add components to your panel. You add a label between those 2 text field, so the next tab after your focused text field (from country) would be the label of code, and then the next is the text field of code.

I'm not sure how to solve the problem in your case. I usually do not use a layout class but rather create the whole layout my own. There could be someone that know how to solve your problem.

i've removed the labels even still the problems resides......i'm not getting the focus on the first click of the Tab button

crossposted, Focus, FocusSubsystem is pretty asynchronous, have to wrap into invokeLater

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.