JTextField焦点不是第一次单击Tab按钮

时间:2012-12-18 10:36:47

标签: java swing autocomplete focus jtextfield

我已经使用两个带有自动完成功能的JTextField完成了一个应用程序 应用程序工作正常但是当鼠标指针位于第一个TextField上时单击Tab键,鼠标焦点不会进入第二个Textfield,而是第二次获得焦点。即为了传递焦点,我们按两次Tab键

任何人都可以告诉我这个问题的原因和解决方案

我的代码如下:

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);
  }
}

提前致谢。

2 个答案:

答案 0 :(得分:3)

为什么重新发明轮子,改为使用

答案 1 :(得分:1)

问题是,您用于显示自动填充的JComboBox是可调焦的。因此,当您点击Tab时,它会关注不可见的ComboBox。如果您在cbInput中声明setupAutoComplete后使用此行,则应解决您的问题:

    cbInput.setFocusable(false);

示例:

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);
            }
        };

        //The important line:
        cbInput.setFocusable(false);

        setAdjusting(cbInput, false);
        for (Object item : items) {
            model.addElement(item);
        }
        ...
}