2016-12-14 112 views
0

为了得到这个结果:JComboBox中的TableCellRenderer似乎失去了它的价值,但价值被保存

enter image description here

我创建了下面的代码。但是一旦组合框关闭,每当我点击面板中的任何位置时,数字似乎回到0(尽管它在后面的代码中发生了变化,正如我看到的使用System.out.println(..))。

这是模型:

public class MenuItem { 
    public boolean getIsChecked() { return isChecked; } 
    public void setIsChecked(boolean checked) { isChecked = checked; } 
    public int getDesiredAmount() { return desiredAmount; } 
    public void setDesiredAmount(int desiredAmount) { this.desiredAmount = desiredAmount; } 
    public String getDescription() { return description; } 
    public ItemType getItemType() { return itemType; } 
    public BigDecimal getPrice() { return price; } 

    private boolean isChecked; 
    private int desiredAmount; 

    private final String description; 
    private final ItemType itemType; 
    private final BigDecimal price; 

    public MenuItem(String description, ItemType type, BigDecimal price) { 
     this.description = description; 
     itemType = type; 
     this.price = price; 
    } 
} 

这是JPanel我用:

public class MenuPanelTable extends JPanel { 
    private static final Integer[] allowedAmounts = new Integer[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 

    public MenuPanelTable(MenuItem[] items) { 
     super(new BorderLayout()); 

     setBorder(BorderFactory.createEmptyBorder(20,20,20,20)); 
     JTable table = new JTable(new TableModel(items)); 
     table.setGridColor(Color.LIGHT_GRAY); 
     table.setRowHeight(table.getRowHeight() + 5); 

     TableColumn amountRow = table.getColumnModel().getColumn(1); 
     DefaultCellEditor cellEditor = new DefaultCellEditor(new JComboBox<>(allowedAmounts)); 
     cellEditor.setClickCountToStart(1); 
     amountRow.setCellEditor(cellEditor); 
     amountRow.setCellRenderer(new AmountsComboBoxRenderer(allowedAmounts)); 

     add(new JScrollPane(table), BorderLayout.CENTER); 
    } 
} 

class AmountsComboBoxRenderer implements TableCellRenderer { 
    private final Integer[] allowedAmounts; 

    public AmountsComboBoxRenderer(Integer[] allowedAmounts) { 
     this.allowedAmounts = allowedAmounts; 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     out.println(String.format("(%d)->%s, [%s][%s]", row + 1, value.toString(), 
       isSelected ? "S" : " ", hasFocus ? "F" : " ")); 

     JComboBox<Integer> cb = new JComboBox<>(allowedAmounts); 
     if (hasFocus) 
      cb.setSelectedItem(value); 
     return cb; 
    } 
} 

class TableModel extends AbstractTableModel { 
    private final MenuItem[] items; 
    public TableModel(MenuItem[] items) { this.items = items; } 
    @Override public int getRowCount() { return items.length; } 
    @Override public int getColumnCount() { return 5; } 

    @Override 
    public Object getValueAt(int rowIndex, int columnIndex) { 
     switch (columnIndex){ 
      case 0 : return items[rowIndex].getIsChecked(); 
      case 1 : return items[rowIndex].getDesiredAmount(); 
      case 2 : return items[rowIndex].getDescription(); 
      case 3 : return items[rowIndex].getItemType(); 
      case 4 : return items[rowIndex].getPrice(); 
      default: return null; 
     } 
    } 

    @Override 
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
     switch (columnIndex){ 
      case 0 : 
       boolean v = (boolean) aValue; 
       if (items[rowIndex].getIsChecked() == v) 
        return; 
       items[rowIndex].setIsChecked(v); 
       fireTableCellUpdated(rowIndex, columnIndex); 
       break; 
      case 1 : 
       int amount = (int) aValue; 
       if (items[rowIndex].getDesiredAmount() == amount) 
        return; 
       items[rowIndex].setDesiredAmount(amount); 
       fireTableCellUpdated(rowIndex, columnIndex); 
       break; 
     } 
    } 

    @Override 
    public String getColumnName(int column) { 
     switch (column) { 
      case 0: return "?"; 
      case 1: return "#"; 
      case 2: return "Course"; 
      case 3: return "Type"; 
      case 4: return "Price"; 
      default: return null; 
     } 
    } 

    @Override 
    public Class<?> getColumnClass(int columnIndex) { 
     switch (columnIndex) { 
      case 0: return Boolean.class; 
      case 1: return Integer.class; 
      case 2: return String.class; 
      case 3: return String.class; 
      case 4: return BigDecimal.class; 
      default: return Object.class; 
     } 
    } 

    @Override 
    public boolean isCellEditable(int rowIndex, int columnIndex) { 
     return columnIndex < 2; 
    } 
} 

我怎样才能让GUI留在所选择的价值?

+0

[SSCCE](http://sscce.org/)或它没有发生。 –

+0

@TT,不幸的是,这对于Java来说并不是真的可能,尤其是w/Swing ......我尽可能地尽量简化它,所以我删除了大量启动样板。 “Short”值与“Self Contained”值相冲突,但它是“Correct(Compilable)”的例子。知道Java/Swing的人可以在几分钟内完成它(只需添加'Main'和容器'JFrame'。如果我添加了它们 - 它会更长......) – Tar

+1

“[SSCCE是]对于Java来说真的不可能“是错误的陈述。堆栈溢出用户已提供Java SSCCE。您的代码可以转换成大约十二行代码的SSCCE。 – VGR

回答

2

从您的渲染器类中删除if (hasFocus)。毕竟,即使细胞没有焦点,你也确实想显示这个值。