我正在尝试使用自定义模型在JTable中实现自动完成ComboBox,但事实证明这比我估计的更难。我读到了我能找到的关于这个的所有内容,但无法理解为什么它不起作用。以下是基于https://today.java.net/pub/a/today/2007/07/19/adding-auto-completion-to-swing-comboboxes.html
的示例我正在使用SwingX的AutoCompleteDecorator。问题是编辑器无法正常工作 - 我无法输入它。我甚至试过添加一个自定义编辑器,虽然在上面的链接上说它不需要它,因为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;
}
}
}
答案 0 :(得分:2)
关注@ kleopatra的指示:我使用的是DefaultCellEditor而不是ComboBoxCellEditor。