2014-03-07 44 views
0

我想在JTable中显示Combobox。对于JTable,我使用TableModel。我已经成功地展示了Combobox(不是它的toString())。问题是我无法查看其内容。组合框必须是不可编辑的。我已经阅读了很多教程,但是我还没有找到TableModel。我发现这个代码:ComboBox未在JTable中显示其内容

JComboBox comboBox = new JComboBox(); 
    comboBox.addItem("Snowboarding"); 
    comboBox.addItem("Rowing"); 
    comboBox.addItem("Knitting"); 
    comboBox.addItem("Speed reading"); 
    comboBox.addItem("Pool"); 
    comboBox.addItem("None of the above"); 
    sportColumn.setCellEditor(new DefaultCellEditor(comboBox)); 

    //Set up tool tips for the sport cells. 
    DefaultTableCellRenderer renderer = 
      new DefaultTableCellRenderer(); 
    renderer.setToolTipText("Click for combo box"); 
    sportColumn.setCellRenderer(renderer); 
} 

我不能使用它有两个原因。我的Combobox的内容是不一样的,他们不使用TableModel。这里是我的代码:

公共类TProfModel扩展的DefaultTableModel实现TableModel的{

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 
private String[] names = { "Nom", "Prénom", "Matière", "Classes" }; 
private Model model; 

public TProfModel(Model model){ 
    this.model = model; 
    fireTableDataChanged(); 
} 


public Class<?> getColumnClass(int col) { 
    return getValueAt(0,col).getClass(); 
} 

public int getColumnCount() { 
    return names.length; 
} 

public String getColumnName(int col) { 
    return names[col]; 
} 

public int getRowCount() { 
    if(model != null) 
     return model.getProfs().size(); 
    return 0; 
} 

public Object getValueAt(int line, int col) { 

    switch (col) { 
    case 0: 
     return model.getProfs().get(line).getNom(); 
    case 1: 
     return model.getProfs().get(line).getPrenom(); 
    case 2: 
     return model.getProfs().get(line).getMatiere(); 
    case 3: 
     return getClasses(line); 
    } 
    return null; 
} 

private JComboBox<String> getClasses(int line) { 
    JComboBox<String> comboBox = new JComboBox<String>(); 
    for(String classe : model.getProfs().get(line).getClasses()) 
     comboBox.addItem(classe); 
    comboBox.setSelectedIndex(0); 
    return comboBox; 
} 


public boolean isCellEditable(int arg0, int arg1) { 
    if(arg1 == 3) 
     return false; 
    return true; 
} 

public void removeTableModelListener(TableModelListener arg0) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void setValueAt(Object object, int line, int col) { 
    switch (col) { 
    case 0: 
     model.getProfs().get(line).setNom((String) object); 
     break; 
    case 1: 
     model.getProfs().get(line).setPrenom((String) object); 
     break; 
    case 2: 
     model.getProfs().get(line).setMatiere((String) object); 
    } 
    model.writeData(); 
} 

}

+0

不要从模型中返回组件。编辑器和渲染器的责任是解释如何最好地显示来自型号 – MadProgrammer

+0

的提供的值以及如何做到这一点?我创建了一个实现TableCellRenderer的类,但我不知道如何使用它。 – Hunsu

+0

返回该列的给定行的值作为编辑器在对其调用setSelectedValue时可以使用的对象,在这种情况下,这将是一个“String”值... – MadProgrammer

回答

3

您可以覆盖getCellEditor(...)方法以返回不同的编辑器。例如:

import java.awt.*; 
import java.awt.event.*; 
import java.util.List; 
import java.util.ArrayList; 
import javax.swing.*; 
import javax.swing.border.*; 
import javax.swing.table.*; 

public class TableComboBoxByRow extends JPanel 
{ 
    List<TableCellEditor> editors = new ArrayList<TableCellEditor>(3); 

    public TableComboBoxByRow() 
    { 
     setLayout(new BorderLayout()); 

     // Create the editors to be used for each row 

     String[] items1 = { "Red", "Blue", "Green" }; 
     JComboBox<String> comboBox1 = new JComboBox<String>(items1); 
     DefaultCellEditor dce1 = new DefaultCellEditor(comboBox1); 
     editors.add(dce1); 

     String[] items2 = { "Circle", "Square", "Triangle" }; 
     JComboBox<String> comboBox2 = new JComboBox<String>(items2); 
     DefaultCellEditor dce2 = new DefaultCellEditor(comboBox2); 
     editors.add(dce2); 

     String[] items3 = { "Apple", "Orange", "Banana" }; 
     JComboBox<String> comboBox3 = new JComboBox<String>(items3); 
     DefaultCellEditor dce3 = new DefaultCellEditor(comboBox3); 
     editors.add(dce3); 

     // Create the table with default data 

     Object[][] data = 
     { 
      {"Color", "Red"}, 
      {"Shape", "Square"}, 
      {"Fruit", "Banana"}, 
      {"Plain", "Text"} 
     }; 
     String[] columnNames = {"Type","Value"}; 
     DefaultTableModel model = new DefaultTableModel(data, columnNames); 
     JTable table = new JTable(model) 
     { 
      // Determine editor to be used by row 
      public TableCellEditor getCellEditor(int row, int column) 
      { 
       int modelColumn = convertColumnIndexToModel(column); 

       if (modelColumn == 1 && row < 3) 
        return editors.get(row); 
       else 
        return super.getCellEditor(row, column); 
      } 
     }; 

     JScrollPane scrollPane = new JScrollPane(table); 
     add(scrollPane); 

    } 
    private static void createAndShowUI() 
    { 
     JFrame frame = new JFrame("Table Combo Box by Row"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new TableComboBoxByRow()); 
     frame.setSize(200, 200); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

或者你可以编写一个'TableCellEditor',它能够提取给定行的值和当前选定的值 - 节省了实现你自己的'JTable'的需要......作为另一种选择... – MadProgrammer

+0

谢谢你们。那是我所做的 – Hunsu

3

模型的责任是提供数据,没有别的。编辑和渲染者有责任中断这些数据,并最好决定如何显示。

传递到编辑器的值是getValueAt,这在下面的例子中,无非是String更多的结果,但由于JComboBox已经填充了String值,这将提供编辑器能够找到匹配的值(如果存在有效的匹配)。

所有你需要做的是确保编辑器/渲染器知道如何处理从模型传来的数据...

TableEditorenter image description here

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.DefaultCellEditor; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.table.AbstractTableModel; 

public class TabelEditorExample { 

    public static void main(String[] args) { 
     new TabelEditorExample(); 
    } 

    public TabelEditorExample() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       ShoppingListModel model = new ShoppingListModel(); 
       model.addEntry(new ShoppingEntry(0, null)); 
       model.addEntry(new ShoppingEntry(0, null)); 
       JTable table = new JTable(model); 

       JComboBox cb = new JComboBox(new String[]{ 
        "Apples", 
        "Bananas", 
        "Pears", 
        "Ice-Cream", 
        "World Domination", 
       }); 
       table. 
         getColumnModel(). 
         getColumn(1). 
         setCellEditor(new DefaultCellEditor(cb)); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new JScrollPane(table)); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class ShoppingListModel extends AbstractTableModel { 

     private List<ShoppingEntry> shoppingEntries; 

     public ShoppingListModel() { 
      shoppingEntries = new ArrayList<ShoppingEntry>(25); 
     } 

     public void addEntry(ShoppingEntry entry) { 
      shoppingEntries.add(entry); 
      fireTableRowsInserted(shoppingEntries.size() - 1, shoppingEntries.size() - 1); 
     } 

     @Override 
     public int getRowCount() { 
      return shoppingEntries.size(); 
     } 

     @Override 
     public String getColumnName(int column) { 
      return column == 0 ? "Qty" : "Item"; 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      return columnIndex == 0 ? Integer.class : String.class; 
     } 

     @Override 
     public int getColumnCount() { 
      return 2; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      Object value = null; 
      switch (columnIndex) { 
       case 0: 
        value = shoppingEntries.get(rowIndex).getQty(); 
        break; 
       case 1: 
        value = shoppingEntries.get(rowIndex).getItem(); 
        break; 
      } 
      return value; 
     } 

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

     @Override 
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
      ShoppingEntry entry = shoppingEntries.get(rowIndex); 
      switch (columnIndex) { 
       case 0: 
        int qty = 0; 
        if (aValue instanceof String) { 
         qty = Integer.parseInt(aValue.toString()); 
        } else if (aValue instanceof Integer) { 
         qty = (Integer)aValue; 
        } 
        entry.setQty(qty); 
        break; 
       case 1: 
        entry.setItem(aValue == null ? null : aValue.toString()); 
        break; 
      } 
      fireTableCellUpdated(rowIndex, columnIndex); 
     } 

    } 

    public class ShoppingEntry { 

     private int qty; 
     private String item; 

     public ShoppingEntry(int qty, String item) { 
      this.qty = qty; 
      this.item = item; 
     } 

     public String getItem() { 
      return item; 
     } 

     public int getQty() { 
      return qty; 
     } 

     public void setItem(String item) { 
      this.item = item; 
     } 

     public void setQty(int qty) { 
      this.qty = qty; 
     } 

    } 

} 

你还需要在你重写setValueAtTableModel并更新它,以便更新您提供的模型中的值。

+0

在你的例子中,你已经修复了cb的值。在我的情况下,每个组合框都有自己的值。 – Hunsu

+0

好的,您如何确定每次将哪些值加载到组合框中? – MadProgrammer

+0

我有一个名字的姓氏和一个字符串数组的对象。在我的JTable中,我在comboBox中显示名字,姓氏和字符串数组。 – Hunsu