我已经使用两个带有自动完成功能的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);
}
}
提前致谢。
答案 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);
}
...
}