问题描述
我创建了一个自定义组合框,用于显示订单状态的可能变化。我在这篇文章的帮助下做到了这一点,使用MadProgrammer的代码作为基线:
Changing Dropdown content in a JTable Column in Swing
部分有效。 即使单击组合框后,它已激活并为用户显示了正确的状态选项,它仍然存在以下问题。
用户选择选项后,组合框不会在表中设置所选值。但是,如果用户更改另一个订单的组合框,则会发生更改。如果您单击所选行中不是组合框单元格的其他部分,它也将起作用。
我怀疑这是因为单击时该单元格仅更改为组合框,因此它的行为不像组合框那样。但是我对如何解决它有些迷茫。
非常感谢您的帮助。
这是我代码的相关部分:
编辑:按照安德鲁·汤普森(Andrew Thompson)的建议,我用可复制的示例替换了代码。我将研究MadProgrammer建议的解决方案,并在以后进行更新。
package test;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
public class TestCellEditor {
public static void main(String[] args) {
new TestCellEditor();
}
public TestCellEditor() {
EventQueue.invokelater(new Runnable() {
@Override
public void run() {
List<String> values = new ArrayList<>(5);
values.add("B");
values.add("A");
values.add("O");
values.add("G");
values.add("P");
ComboBoxTableCellEditor editor = new ComboBoxTableCellEditor(values);
DefaultTableModel model = new DefaultTableModel(new Object[]{"Status"},5);
JTable table = new JTable(model);
table.getColumnModel().getColumn(0).setCellEditor(editor);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeto(null);
frame.setVisible(true);
}
});
}
public class ComboBoxTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private JComboBox editor;
private List<String> masterValues;
public ComboBoxTableCellEditor(List<String> masterValues) {
this.editor = new JComboBox();
this.masterValues = masterValues;
}
@Override
public Object getCellEditorValue() {
return editor.getSelectedItem();
}
@Override
public Component getTableCellEditorComponent(JTable table,Object value,boolean isSelected,int row,int column) {
DefaultComboBoxModel model = new DefaultComboBoxModel(masterValues.toArray(new String[masterValues.size()]));
for (int index = 0; index < table.getRowCount(); index++) {
}
editor.setModel(model);
editor.setSelectedItem(value);
return editor;
}
}
}
解决方法
按照@camickr的建议,我设法实现了一个更简单的解决方案。
我将其放在填充表格的方法上
table.getColumnModel().getColumn(5).setCellEditor(getCellEditor(status));
public List<TableCellEditor> TableComboBoxByRow(){
// Create the editors to be used for each row
List<TableCellEditor> editors = new ArrayList<TableCellEditor>(3);
String[] items1 = { "I","C","F" };
JComboBox comboBox1 = new JComboBox( items1 );
DefaultCellEditor dce1 = new DefaultCellEditor( comboBox1 );
editors.add( dce1 );
String[] items2 = { "E" };
JComboBox comboBox2 = new JComboBox( items2 );
DefaultCellEditor dce2 = new DefaultCellEditor( comboBox2 );
editors.add( dce2 );
String[] items3 = { "ET" };
JComboBox comboBox3 = new JComboBox( items3 );
DefaultCellEditor dce3 = new DefaultCellEditor( comboBox3 );
editors.add( dce3 );
String[] items4 = { "F" };
JComboBox comboBox4 = new JComboBox( items4 );
DefaultCellEditor dce4 = new DefaultCellEditor( comboBox4 );
editors.add( dce4 );
return editors;
}
public TableCellEditor getCellEditor(String status)
{
if(estado.equals("I") || estado.equals("C")){
return TableComboBoxByRow().get(0);
}
else if(estado.equals("E"))
{
return TableComboBoxByRow().get(1);}
else if(estado.equals("ET"))
{
return TableComboBoxByRow().get(2);
}else{
return TableComboBoxByRow().get(3);
}
}
非常感谢您!
,此方法将仅覆盖DefaultCellEditor的getTableCellEditorComponent(...)
方法,以根据正在编辑的当前行中的值来重置组合框的模型。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class StateCellEditor extends DefaultCellEditor
{
private int lookupColumn;
private HashMap<Object,DefaultComboBoxModel<?>> map;
public StateCellEditor(JComboBox<?> comboBox,int lookColumn,HashMap<Object,DefaultComboBoxModel<?>> map)
{
super(comboBox);
this.lookupColumn = lookupColumn;
this.map = map;
}
@Override
public Component getTableCellEditorComponent(JTable table,Object value,boolean isSelected,int row,int column)
{
Component c = super.getTableCellEditorComponent(table,value,isSelected,row,column);
JComboBox<?> comboBox = (JComboBox<?>)c;
Object lookup = table.getModel().getValueAt(row,lookupColumn);
DefaultComboBoxModel model = map.get( lookup );
comboBox.setModel( model );
return comboBox;
}
private static void createAndShowUI()
{
HashMap<Object,DefaultComboBoxModel<?>> map = new HashMap<>();
map.put("Color",new DefaultComboBoxModel<Object>( new String[]{ "Red","Blue","Green" } ));
map.put("Shape",new DefaultComboBoxModel<Object>( new String[]{ "Circle","Square","Triangle" } ));
map.put("Fruit",new DefaultComboBoxModel<Object>( new String[]{ "Apple","Orange","Banana" } ));
JPanel panel = new JPanel( new BorderLayout() );
panel.setLayout( new BorderLayout() );
// Create the table with default data
Object[][] data =
{
{"Color","Red"},{"Shape","Square"},{"Fruit","Banana"}
};
String[] columnNames = {"Type","Value"};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
JTable table = new JTable(model);
DefaultCellEditor dce = new StateCellEditor(new JComboBox<Object>(),map);
table.getColumnModel().getColumn(1).setCellEditor(dce);
JScrollPane scrollPane = new JScrollPane( table );
panel.add( scrollPane );
JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel,BorderLayout.CENTER);
frame.setSize(200,200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}