我正在使用 GlazedLists 的 AutoCompleteSupport 来包装用作 JTable 的单元格编辑器的 JComboBox,当我在编辑器中键入不在模型中的值时,我遇到了获取 selectedItem 的问题。
在您在 ComboBox 中键入不在列表中的内容后,问题出现在 stopCellEditing 方法中。即使在编辑器中输入了某些内容,当从 stopCellEditing 调用 getItem() 时,也会返回 null。请从下面的代码中查看 65。
我想从编辑器中获取项目,以便能够将其添加到 ComboBox 模型中。
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.swing.AutoCompleteSupport;
import java.awt.Component;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.HashMap;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class TestComboBoxGlazedLists {
public static void main(String[] args) {
TestComboBoxGlazedLists test = new TestComboBoxGlazedLists();
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
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
TestComboBoxGlazedLists.UserRepository rep = new TestComboBoxGlazedLists.UserRepository();
TestComboBoxGlazedLists.UserInfo[] comboElements = rep.getAllUsers();
DefaultComboBoxModel model = new DefaultComboBoxModel(comboElements);
JComboBox comboBox = new JComboBox(model);
// GlazedLists
DefaultCellEditor cellEditor = new DefaultCellEditor(comboBox) {
private Object originalValue;
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
originalValue = value;
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
@Override
public boolean stopCellEditing() {
JComboBox comboBox = (JComboBox) getComponent();
ComboBoxModel comboModel = comboBox.getModel();
// this value is null when the selected item is not from the list
Object editingValue = getCellEditorValue();
// Needed because your TableModel is empty
if (editingValue == null) {
return super.stopCellEditing();
}
int selectedIndex = -1;
int modelSize = comboModel.getSize();
for (int i = 0; i < modelSize; i++) {
if (editingValue.equals(comboModel.getElementAt(i))) {
selectedIndex = i;
}
}
// Selecting item from model
if (!(selectedIndex == -1)) {
return super.stopCellEditing();
}
if (!(editingValue instanceof TestComboBoxGlazedLists.UserInfo)) {
// Confirm addition of new value
int result = JOptionPane.showConfirmDialog(
comboBox.getParent(),
"Add (" + editingValue + ") to table?",
"Update Model",
JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
TestComboBoxGlazedLists.UserInfo newUser = new TestComboBoxGlazedLists.UserInfo(editingValue.toString(), null);
comboBox.addItem(newUser);
comboBox.setSelectedItem(newUser);
return super.stopCellEditing();
}
}
return false;
}
};
// needs to be invoked from Event Dispatch Thread
SwingUtilities.invokeLater(new TestComboBoxGlazedLists.AutocompleteComboRunnable(table, comboBox));
// end GlazedLists
table.getColumn("A").setCellEditor(cellEditor);
table.getColumn("A").setCellRenderer(new TestComboBoxGlazedLists.CustomTableCellRenderer());
// pack and show frame
frame.pack();
frame.setVisible(true);
}
public class AutocompleteComboRunnable implements Runnable {
private JTable mTable;
private JComboBox mComboBox;
public AutocompleteComboRunnable(JTable table, JComboBox comboBox) {
mTable = table;
mComboBox = comboBox;
}
@Override
public void run() {
TextFilterator textFilterator = GlazedLists.textFilterator("firstName");
// ComboBoxCellEditor cellEditor = new ComboBoxCellEditor(comboBox);
TestComboBoxGlazedLists.UserRepository rep = new TestComboBoxGlazedLists.UserRepository();
AutoCompleteSupport support = AutoCompleteSupport.install(mComboBox,
GlazedLists.eventListOf(rep.getAllUsers()),
textFilterator,
new TestComboBoxGlazedLists.UserInfoFormat());
support.setStrict(false);
}
}
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"
TestComboBoxGlazedLists.UserInfo user = (TestComboBoxGlazedLists.UserInfo) value;
return super.getTableCellRendererComponent(table, user.getFirstName(), isSelected, hasFocus, row, column);
} else {
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
}
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 {
TestComboBoxGlazedLists.UserInfo[] comboElements;
HashMap<String, TestComboBoxGlazedLists.UserInfo> objectsMap;
public UserRepository() {
comboElements = new TestComboBoxGlazedLists.UserInfo[5];
comboElements[0] = new TestComboBoxGlazedLists.UserInfo("John", "Doe");
comboElements[1] = new TestComboBoxGlazedLists.UserInfo("Betty", "Doe");
comboElements[2] = new TestComboBoxGlazedLists.UserInfo("Elenor", "Smith");
comboElements[3] = new TestComboBoxGlazedLists.UserInfo("Helen", "Kelly");
comboElements[4] = new TestComboBoxGlazedLists.UserInfo("Joe", "Black");
objectsMap = new HashMap<>();
for (int i = 0; i < 5; i++) {
objectsMap.put(comboElements[i].getFirstName(), comboElements[i]);
}
}
public TestComboBoxGlazedLists.UserInfo getUserInfo(String name) {
return objectsMap.get(name);
}
public TestComboBoxGlazedLists.UserInfo[] getAllUsers() {
return comboElements;
}
}
private class UserInfoFormat extends Format {
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
if (obj != null) {
toAppendTo.append(((TestComboBoxGlazedLists.UserInfo) obj).getFirstName());
}
return toAppendTo;
}
@Override
public Object parseObject(String source, ParsePosition pos) {
TestComboBoxGlazedLists.UserRepository rep = new TestComboBoxGlazedLists.UserRepository();
return rep.getUserInfo(source.substring(pos.getIndex()));
}
}
}