4

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

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();       

}

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

4

2 回答 2

4

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

最好的解决方案是扩展DefaltTableCellRenderer和覆盖该getTableCellRendererComponent方法,并根据需要逐个单元格地应用图标

您可以通过为给定Class类型定义默认渲染器或直接应用于列来应用渲染器

查看如何使用 JTables和特别是使用自定义渲染器

更新示例

这是一种方法,还有更多...

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;
        }        
    }    
}

更新

为什么不使用JButton/ TableCellEditor这就是为什么

于 2012-10-21T06:28:39.227 回答
2

这是通过可以扩展JLabel的自定义单元格渲染器完成的。您可以轻松设置JLabel的图标。这是一个合适的例子

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

于 2012-10-21T06:10:19.173 回答