将 JComboBox 添加到 JTable 单元格。所选项目不保留

Adding a JComboBox to a JTable cell. Selected item doesn't stay

我在这里查看了一些帖子,但找不到答案。

我已成功将 JComboBox 添加到 Jtable 单元格。但是,selected 项目并未 "remembered"。

更具体地说:

1) Select A 行组合框中的一个项目

2) 转到select B 行的组合框,但是A 行显示的项目消失了(任何时候失去焦点,A 行组合框selection 消失)

3) 回到A行,选择被记住。

需要明确的是,信息不会丢失。虽然组合框没有直观地显示选择了什么设备,但 selection 被保存了下来。但是,我希望用户能够直观地看到他们刚刚 select 编辑的内容,而不必再次 select 该行。

这让我相信我使用的自定义渲染器一定有错误

下面是相关代码。

Table型号 (注意Level2Area等同于Equipment):

public class PreDefJobPlanDialogDataTable extends CygnusAbstractTableModel{

 private static final long serialVersionUID = 1344977933386754731L;

 static final ColumnData columns[] = {
    new ColumnData( "Sel." , 25, 10000, JLabel.LEFT),
    new ColumnData( "Type", 25, 10000, JLabel.LEFT),
    new ColumnData( "Status", 25,  10000,JLabel.LEFT ),
    new ColumnData( "Title", 100,  10000,JLabel.LEFT ),
    new ColumnData( "Equipment Class", 50, 10000, JLabel.LEFT),
    new ColumnData( "Equipment", 100, 10000, JLabel.LEFT)
};

...

public boolean isCellEditable(int rowIndex, int columnIndex) {
    boolean ret = false;
    if( columnIndex == 0 || columnIndex == 5 ) {
        ret = true;             
    }
    return ret;
}

...

public Object getValueAt(int rowIndex, int columnIndex) {
    Object ret = " ";

    if( rowIndex >= 0 && rowIndex < getRowCount() ) {
        PreDefJobPlan obj = (PreDefJobPlan)modelData.get( rowIndex );
        switch( columnIndex ) {

            case 0: ret = obj.getGroupFlag();
            break;
            case 1: ret = obj.getType();
            break;
            case 2: ret = obj.getStatus();
            break;
            case 3: ret = obj.getTitle();
            break;
            case 4: ret = obj.getLevel1Area();
            break;
            case 5: ret = obj.getLevel2Area();
            break;
            case 9: ret = obj.getPreDefJobPlanID();
            break;
            default: ret = " ";
        }
    }
    return ret;
}

...

public void setValueAt( Object obj, int row, int col ) {
    // get the object
    PreDefJobPlan o = (PreDefJobPlan) this.modelData.get( row );
    switch( col ) {
        case 0:
            o.setGroupFlag((Boolean) obj);
        break;
        case 5:
            o.setLevel2Area((Equipment) obj);
        break;
        default: ;
    }
}

正在创建 Table:

protected void createTable() {
    PreDefJobPlanDialogDataTable dataModel = new PreDefJobPlanDialogDataTable();
    dataModel.setTimeOffset( 0 );

    this.view.getOrdersTable().setHighlighters(HighlighterFactory.createAlternateStriping());
    this.view.getOrdersTable().setAutoCreateColumnsFromModel( false );
    this.view.getOrdersTable().setModel( dataModel );
    this.view.getOrdersTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    this.view.getOrdersTable().setTransferHandler(new TableRowTransferHandler(this.view.getOrdersTable())); 

  for( int i = 0; i < dataModel.getColumnCount(); i++ ) {   
            if( i== 0 ) {
                ...
            }
            else if (i == 5){

                TableCellRenderer renderer = new ComboCellRenderer(); 
                ca.cygnusconsulting.utilities.ColumnData col = dataModel.getColumn( i );
                JComboBox tableCheckBox = new JComboBox();
                tableCheckBox.setModel( lvl1Model );
                tableCheckBox.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
                tableCheckBox.setBackground(this.view.getOrdersTable().getBackground());
                TableCellEditor editor = new ComboBoxCellEditor(tableCheckBox);
                TableColumnExt column = new TableColumnExt( i, col.getWidth(), renderer, editor );
                column.setMaxWidth(col.getMaxWidth());
                this.view.getOrdersTable().addColumn( column ); 
            }
            else{
                ...
            }
        } 

渲染器:

public class ComboCellRenderer extends JComboBox implements TableCellRenderer {

protected static Border noFocusBorder = new EmptyBorder(1,1,1,1);
protected static Border focusBorder = UIManager.getBorder("Table.focusCellHighlightBorder");

 public ComboCellRenderer() {
  super();
  setOpaque(true);

 }

  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
  boolean hasFocus, int row, int column) {

    setBackground(isSelected && !hasFocus ? table.getSelectionBackground() : table.getBackground());
    setForeground(isSelected && !hasFocus ? table.getSelectionForeground() : table.getForeground());
    setFont(table.getFont());
    setSelectedItem(value);

  return this;
  }


}

有没有人有什么合理的建议,或者对此有什么见解?

通常您应该使用默认的单元格渲染器来显示您的单元格内容,并且只在编辑时显示组合框。

要理解 JTable 单元格渲染器的一个关键概念是 a single cell renderer is generally used to draw all of the cells that contain the same type of data

如果您特别希望将组合框用于渲染单元格,那么您的单元格为空的原因是自定义渲染器组合框没有添加项目。您应该使用与单元格编辑器组合框相同的值填充单元格渲染器组合框。