Java Jtable内的自动完成JCombobox-在编辑器中键入不起作用

Java Jtable内的自动完成JCombobox-在编辑器中键入不起作用,java,swing,autocomplete,jtable,jcombobox,Java,Swing,Autocomplete,Jtable,Jcombobox,我试图使用自定义模型在JTable中实现一个自动完成组合框,但事实证明这比我估计的要难。我读了所有我能找到的关于这一点的资料,无法理解为什么它不起作用。下面是一个基于 我正在使用SwingX的自动完成计算器。问题是编辑器不工作-我无法输入它。我甚至试着添加一个自定义编辑器,尽管上面的链接上说不需要它,因为AutoCompleteDecorator会为您处理它 import java.awt.Component; import java.util.HashMap; import javax.swi

我试图使用自定义模型在JTable中实现一个自动完成组合框,但事实证明这比我估计的要难。我读了所有我能找到的关于这一点的资料,无法理解为什么它不起作用。下面是一个基于

我正在使用SwingX的自动完成计算器。问题是编辑器不工作-我无法输入它。我甚至试着添加一个自定义编辑器,尽管上面的链接上说不需要它,因为AutoCompleteDecorator会为您处理它

import java.awt.Component;
import java.util.HashMap;
import javax.swing.ComboBoxEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import org.jdesktop.swingx.JXComboBox;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
import org.jdesktop.swingx.autocomplete.ObjectToStringConverter;

public class TestComboCellEditor {

    public static void main(String[] args) {

        TestComboCellEditor test = new TestComboCellEditor();
        test.go();
    }

    public void go() {

        //create the frame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // create and add a tabbed pane to the frame
        JTabbedPane tabbedPane = new JTabbedPane();
        frame.getContentPane().add(tabbedPane);
        //create a table and add it to a scroll pane in a new tab
        final JTable table = new JTable(new DefaultTableModel(new Object[]{"A", "B"}, 5));
        JScrollPane scrollPane = new JScrollPane(table);
        tabbedPane.addTab("test", scrollPane);

        // create a simple JComboBox and set is as table cell editor on column A
        UserRepository rep = new UserRepository();
        UserInfo[] comboElements = rep.getAllUsers();
        JXComboBox comboBox = new JXComboBox(comboElements);
        comboBox.setEditable(true);
        comboBox.setRenderer(new CustomListCellRenderer());
//        comboBox.setEditor(new UserInfoEditor(comboBox.getEditor()));

        // apply autocomplete decorator
        AutoCompleteDecorator.decorate(comboBox, new ObjectToStringConverter() {
            @Override
            public String getPreferredStringForItem(Object item) {
                if (item instanceof UserInfo) {
                    return ((UserInfo) item).getFirstName();
                } else {
                    return null;
                }

            }
        });

        table.getColumn("A").setCellEditor(new DefaultCellEditor(comboBox));
        table.getColumn("A").setCellRenderer(new CustomTableCellRenderer());

        // pack and show frame
        frame.pack();
        frame.setVisible(true);
    }

    public class CustomTableCellRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (value != null) {
                // this is used to extract the data you want to display in the table from your "custom model"
                UserInfo user = (UserInfo) value;
                return super.getTableCellRendererComponent(table, user.getFirstName(), isSelected, hasFocus, row, column);
            } else {
                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            }
        }
    }

    public class CustomListCellRenderer extends DefaultListCellRenderer {

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof UserInfo) {
                JLabel result = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                UserInfo userInfo = (UserInfo) value;
                result.setText(userInfo.getFirstName());
                return result;
            } else {
                return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            }
        }
    }

    public class UserInfo {

        private String firstName;
        private String lastName;

        public UserInfo(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }
    }

    public class UserRepository {

        private UserInfo[] comboElements;
        private HashMap<String, UserInfo> objectsMap;

        public UserRepository() {
            comboElements = new UserInfo[5];
            comboElements[0] = new UserInfo("John", "Doe");
            comboElements[1] = new UserInfo("Betty", "Doe");
            comboElements[2] = new UserInfo("Elenor", "Smith");
            comboElements[3] = new UserInfo("Helen", "Kelly");
            comboElements[4] = new UserInfo("Joe", "Black");
            objectsMap = new HashMap<>();
            for (int i = 0; i < 5; i++) {
                objectsMap.put(comboElements[i].getFirstName(), comboElements[i]);
            }
        }

        public UserInfo getUserInfo(String name) {
            return objectsMap.get(name);
        }

        public UserInfo[] getAllUsers() {
            return comboElements;
        }
    }

    public class UserInfoEditor extends BasicComboBoxEditor {

        public UserInfoEditor(ComboBoxEditor origEditor) {
            super();
            editor.setBorder(((JComponent) origEditor.getEditorComponent())
                    .getBorder());
        }

        @Override
        public void setItem(Object anObject) {
            if (anObject instanceof UserInfo) {
                super.setItem(((UserInfo) anObject).getFirstName());
            } else {
                super.setItem(anObject);
            }
        }

        @Override
        public Object getItem() {
            Object superRes = super.getItem();
            if (superRes instanceof String) {
                UserRepository rep = new UserRepository();
                UserInfo result = rep.getUserInfo((String) superRes);
                return result;
            }
            return superRes;
        }
    }
}
导入java.awt.Component;
导入java.util.HashMap;
导入javax.swing.ComboBoxEditor;
导入javax.swing.DefaultCellEditor;
导入javax.swing.DefaultListCellRenderer;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JList;
导入javax.swing.JScrollPane;
导入javax.swing.JTabbedPane;
导入javax.swing.JTable;
导入javax.swing.plaf.basic.BasicComboxeditor;
导入javax.swing.table.DefaultTableCellRenderer;
导入javax.swing.table.DefaultTableModel;
导入org.jdesktop.swingx.JXComboBox;
导入org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
导入org.jdesktop.swingx.autocomplete.objecttoString转换器;
公共类TestComboCellEditor{
公共静态void main(字符串[]args){
TestComboCellEditor test=新建TestComboCellEditor();
test.go();
}
公开作废go(){
//创建框架
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建选项卡式窗格并将其添加到框架中
JTabbedPane tabbedPane=新的JTabbedPane();
frame.getContentPane().add(选项卡窗格);
//创建表格并将其添加到新选项卡中的滚动窗格中
最终的JTable表=新的JTable(新的DefaultTableModel(新对象[]{“A”,“B”},5));
JScrollPane scrollPane=新的JScrollPane(表);
addTab(“测试”,滚动窗格);
//创建一个简单的JComboBox,并将其设置为列a上的表格单元编辑器
UserRepository=newuserrepository();
UserInfo[]comboElements=rep.getAllUsers();
JXComboBox组合框=新的JXComboBox(组合元素);
comboBox.setEditable(真);
setRenderer(新的CustomListCellRenderer());
//setEditor(新的UserInfoEditor(comboBox.getEditor());
//应用自动完成装饰器
装饰(组合框,新ObjectToStringConverter()){
@凌驾
公共字符串getPreferredStringForItem(对象项){
if(UserInfo的项目实例){
return((UserInfo)项).getFirstName();
}否则{
返回null;
}
}
});
table.getColumn(“A”).setCellEditor(新的DefaultCellEditor(组合框));
table.getColumn(“A”).setCellRenderer(新的CustomTableCellRenderer());
//包装展示架
frame.pack();
frame.setVisible(true);
}
公共类CustomTableCellRenderer扩展了DefaultTableCellRenderer{
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、布尔isSelected、布尔hasFocus、int行、int列){
if(值!=null){
//这用于从“自定义模型”提取要在表中显示的数据
UserInfo user=(UserInfo)值;
返回super.getTableCellRenderComponent(表,user.getFirstName(),isSelected,hasFocus,行,列);
}否则{
返回super.getTableCellRenderComponent(表、值、isSelected、hasFocus、行、列);
}
}
}
公共类CustomListCellRenderer扩展了DefaultListCellRenderer{
@凌驾
公共组件getListCellRenderComponent(JList列表、对象值、int索引、布尔isSelected、布尔cellHasFocus){
if(UserInfo的值instanceof){
JLabel结果=(JLabel)super.getListCellRenderComponent(列表、值、索引、isSelected、cellHasFocus);
UserInfo UserInfo=(UserInfo)值;
result.setText(userInfo.getFirstName());
返回结果;
}否则{
返回super.getListCellRenderComponent(列表、值、索引、isSelected、cellHasFocus);
}
}
}
公共类用户信息{
私有字符串名;
私有字符串lastName;
public UserInfo(String firstName、String lastName){
this.firstName=firstName;
this.lastName=lastName;
}
公共字符串getFirstName(){
返回名字;
}
公共字符串getLastName(){
返回姓氏;
}
}
公共类用户存储库{
私有用户信息[]组合元素;
私有HashMap对象映射;
公共用户存储库(){
comboElements=新用户信息[5];
comboElements[0]=新用户信息(“John”、“Doe”);
comboElements[1]=新用户信息(“Betty”、“Doe”);
comboElements[2]=新用户信息(“Elenor”、“Smith”);
comboElements[3]=新用户信息(“Helen”、“Kelly”);
comboElements[4]=新用户信息(“Joe”、“Black”);
objectsMap=newHashMap();
对于(int i=0;i<5;i++){
objectsMap.put(comboElements[i].getFirstName(),comboElements[i]);
}
}
public UserInfo getUserInfo(字符串名称){
返回objectsMap.get(名称);
}
公共用户信息[]getAllUsers(){
返回组合元素;
}
}
公共类UserInfoEditor扩展了BasicComboxeditor{
公共用户信息编辑器(ComboBoxEditor或origEditor){
超级();
editor.setboorder(((JComponent)origEditor。