如何在JTable单元格中设置图标?

时间:2012-10-21 06:03:32

标签: java swing icons jtable imageicon

我正在尝试在Jtable的单元格中添加图像Icon。我有一个如下所述的代码。我该怎么做?

package com.orb;
private final LinkedList<Product> list= new LinkedList<Product>();
private final LinkedList<Boolean> checkList = new LinkedList<Boolean>();
public void addItem(Product customer) {
    list.add(customer);
    checkList.add(false);
    checkList.remove(true);
    fireTableDataChanged();
  }

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

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

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Object obj = null;

    if(columnIndex==4){
        setTotal(list.get(rowIndex));
    }

    switch (columnIndex){
        case 0: obj= list.get(rowIndex).getCode() ;break;
        case 1: obj=list.get(rowIndex).getDescription(); break;
        case 2: obj=list.get(rowIndex).getQuantity();break;
        case 3: obj=list.get(rowIndex).getPrice();break;            
        case 4: obj=list.get(rowIndex).getTotal();break;
    }
    return obj;
}

@Override
public Class<?> getColumnClass(int arg0) {

    switch(arg0){
    case 0: case 1: return String.class; 
    case 2: return Integer.class; 
    case 3: case 4: return Double.class;

    //case 5: return ImageIcon.class;
    }
    return super.getColumnClass(arg0);
}

@Override
public boolean isCellEditable(int arg0, int arg1) {
    boolean isCellEditable = false;
    switch(arg1){
    case 2: case 3: isCellEditable= true;break;
    default: isCellEditable= false;break;
    }
    return isCellEditable;
    //return super.isCellEditable(arg0, arg1);
}

@Override
public void setValueAt(Object arg0, int arg1, int arg2) {
    System.out.println("Value seted" +arg0 + arg1 + arg2);

    switch(arg2){
    case 0: break;
    case 1: break;
    case 2: list.get(arg1).setQuantity((Integer)arg0); setTotal(list.get(arg1)); break;
    case 3: list.get(arg1).setPrice((Double)arg0); setTotal(list.get(arg1));break;          
    case 4: list.get(arg1).setTotal((Double)arg0);break;

       //case 0: checkList.set(arg1, (Boolean)arg0);break;
       default:break;
    }

    fireTableDataChanged();
}

public LinkedList<Product> getList() {
    LinkedList<Product> temp = new LinkedList<Product>();
    int index=-1;
    for(Boolean isSelected:checkList){
        index++;
        if(isSelected){
            temp.add(list.get(index));
        }
    }
    return temp;
}

public void deleteRow(int rowNubmer)
{
    list.remove(rowNubmer);     
    fireTableDataChanged();
}

public void setTotal(Product product){
    Double total = 0.0d;
    total = product.getQuantity ()* product.getPrice();
    product.setTotal(total);

}
@Override
public void fireTableDataChanged() {
    super.fireTableDataChanged();       

}

我有一个像上面这样的桌子模型。我想在表格单元格中添加图像图标,并希望在按下该图标时删除单元格。我该怎么做这个代码? 请给我完整的描述。

2 个答案:

答案 0 :(得分:4)

您可以使用由JLabel支持的DefaltTableCellRenderer,然后您可以使用DefaltTableCellRenderer来设置图标。

最佳解决方案是扩展getTableCellRendererComponent并覆盖Class方法并根据需要在单元格上应用图标

您可以通过为给定的public class TestTable { public static void main(String[] args) { new TestTable(); } public TestTable() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } JTable table = new JTable(); table.setGridColor(Color.LIGHT_GRAY); table.setShowGrid(true); table.setShowHorizontalLines(true); table.setShowVerticalLines(true); table.setModel(new TestTableModel()); table.getColumn("X").setCellRenderer(new DeleteCellRenderer()); table.getColumn("X").setCellEditor(new DeleteCellEditor()); JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new JScrollPane(table)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } protected class TestTableModel extends AbstractTableModel { private List<RowData> rowData; public TestTableModel() { rowData = new ArrayList<RowData>(25); for (int index = 0; index < 10; index++) { rowData.add(new RowData(index)); } } @Override public String getColumnName(int column) { return column == 0 ? "Text" : "X"; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { RowData rd = rowData.get(rowIndex); return rd.isDeletable(); } @Override public int getRowCount() { return rowData.size(); } @Override public int getColumnCount() { return 2; } @Override public Object getValueAt(int rowIndex, int columnIndex) { RowData rd = rowData.get(rowIndex); return columnIndex == 0 ? rd.getText() : rd.isDeletable(); } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { RowData rd = rowData.get(rowIndex); if (columnIndex == 1) { if (aValue instanceof Boolean && (Boolean)aValue) { rowData.remove(rd); fireTableRowsDeleted(rowIndex, rowIndex); } } } } public class RowData { private String text; private boolean deletable; public RowData(int row) { text = "Row " + row; deletable = Math.round(Math.random() * 1) == 0; } public String getText() { return text; } public boolean isDeletable() { return deletable; } } public class DeleteCellRenderer extends DefaultTableCellRenderer { public DeleteCellRenderer() { try { BufferedImage img = ImageIO.read(getClass().getResource("/Delete.png")); setIcon(new ImageIcon(img)); } catch (IOException ex) { ex.printStackTrace(); } } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setText(null); if (value instanceof Boolean && (Boolean)value) { setEnabled(true); } else { setEnabled(false); } return this; } } public class DeleteCellEditor extends AbstractCellEditor implements TableCellEditor { private JLabel label; public DeleteCellEditor() { label = new JLabel("Delete"); } @Override public Object getCellEditorValue() { return true; } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { stopCellEditing(); } }); return label; } @Override public boolean isCellEditable(EventObject e) { return true; } } } 类型定义默认渲染器或直接为列

来应用渲染器

特别查看How to Use JTablesUsing Custom Renderers

更新了示例

这是 A 方法,还有更多......

JButton

<强>更新

为什么不使用TableCellEditor / {{1}}? Here's why

答案 1 :(得分:2)

这是通过可以扩展 JLabel 的自定义单元格渲染器完成的。您可以轻松设置 JLabel 的图标。这是suitable example

Renderrer是在 JTable 调用 getTableCellRendererComponent 传递单元格状态和内容之后必须将自身绘制为表格单元格的组件。然后,渲染器通常会自行设置属性并返回 this 。只要渲染器扩展 Component ,渲染器也可以返回其他对象。