枝! 我有一个JTable。此JTable的列由JComboBox呈现。 我希望能够根据第1栏中选择的值更改第2栏的项目。
例如,如果用户在第1列中选择Microsoft,则在第2列中,他/她可以选择ado,wpf等。
有可能吗? 如果有可能,应该听哪些事件呢?
答案 0 :(得分:0)
也许您可以根据此代码为基础;
table.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
}
}
);
这是一个有趣的页面:click
答案 1 :(得分:0)
只需创建自己的TableCellEditor,即在调用getTableCellEditorComponent时准备JComboBox的模型。像这样:
class MyEditor extends DefaultCellEditor{
public MyEditor() {
super(new JComboBox());
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
JComboBox combo = (JComboBox)editorComponent;
Object column1Value = table.getValueAt(row, column-1);
Object[] options = ... create options based on other value
combo.setModel(new DefaultComboBoxModel(options));
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
}
答案 2 :(得分:0)
Combo Box Table Editor为此提供了一种可能的解决方案。
答案 3 :(得分:0)
您在TableModel
中使用了什么作为值?
一种解决方案是定义一个类,比如说CategoryValue
,它代表一个可能的项目列表和一个选定的项目,并使用它;然后监听TableModelEvents
,当第0列中的值发生变化时,在第1列中设置相应的值。下面是一个简单的例子。
首先,TableModelListener
:
model.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
if (e.getColumn() == 0) {
int firstRow = e.getFirstRow();
int lastRow = e.getLastRow();
for (int row = firstRow; row <= lastRow; row++) { // note <=, not <
CategoryValue parentValue = ((CategoryValue) model.getValueAt(row, 0));
String parentSelection = parentValue.getSelection();
List<String> childCategories = getChildCategories(parentSelection);
CategoryValue newChildValue = new CategoryValue(childCategories);
model.setValueAt(newChildValue , row, 1);
}
}
}
});
(实施getChildCategories(String)
取决于数据的来源,但可能就像Map<String, List<String>>
一样简单。)
接下来是值类:
public class CategoryValue {
private final String selection;
private final List<String> categories;
public CategoryValue(List<String> categories) {
this(categories, categories.get(0));
}
public CategoryValue(List<String> categories, String selection) {
assert categories.contains(selection);
this.categories = categories;
this.selection = selection;
}
public String getSelection() {
return selection;
}
public List<String> getCategories() {
return categories;
}
@Override
public String toString() {
return selection;
}
}
最后,值类的自定义单元格编辑器:
public class CategoryCellEditor extends DefaultCellEditor {
public CategoryCellEditor() {
super(new JComboBox());
}
static List<CategoryValue> allValues(List<String> categories) {
List<CategoryValue> allValues = new ArrayList<CategoryValue>();
for (String value: categories) {
allValues.add(new CategoryValue(categories, value));
}
return Collections.unmodifiableList(allValues);
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
CategoryValue categoryValue = (CategoryValue) value;
List<String> categories = categoryValue.getCategories();
List<CategoryValue> allValues = CategoryValue.allValues(categories);
ComboBoxModel cbModel = new DefaultComboBoxModel(allValues.toArray());
((JComboBox)editorComponent).setModel(cbModel);
return super.getTableCellEditorComponent(table, categoryValue,
isSelected, row, column);
}
}
所有事件都是通过一个事件监听器完成的,并且一个很好的奖励是该事件监听器不关心如何编辑/更新表,或者编辑/更新来自何处。
编辑添加:或者,使用一些业务对象表示表的每一行,该业务对象捕获为特定行所做的所有选择,并让CellEditor
从中获取可用的选项业务对象(使用row
参数getTableCellEditorComponent()
来获取业务对象)。事件机制将保持不变。这样做的好处是,从业务对象中读取选定的值可能比刮掉表格更容易。