JTable - 如何为特定列中的每一行插入新的JLabel?

时间:2014-05-06 13:12:32

标签: java swing jtable jlabel

我现在正在互联网上寻找约5个小时来调试这个问题。基本上我无法找到任何人试图为特定列中的每一行添加新JLabel的地方。

功能说明:我得到一个文件网址,我接受postFix,通常是xlsx或 doc - 这个后缀我希望在一个JLabel中与Excel或Doc联合显示 Icon -.-但我当前的代码所做的只是一遍又一遍地绘制相同的JLabel,因为它只设置CellRenderer一次并在所有行上使用它来表示我在每次迭代的for循环中设置它的事实 - 我的所有代码都是正确的,直到渲染器只被调用一次。

所以我的问题如下 - 我如何为每一行添加一个新的JLabel 在一列? -

我的代码如下。

我的TableCellRenderer:

 public class JLabelRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = -166379583761969293L;
// private String fileExtension;
// private JLabel label;
private LogEntry log;
private JLabel label;

public JLabelRenderer(LogEntry log) {
    label = new JLabel();
    System.out.println("makeing a new JLabelRenderer");
    this.log = log;
}

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

    label = (JLabel) super.getTableCellRendererComponent(table, value,
            isSelected, hasFocus, row, column);

    System.out.println(log.getFileExtension());
    if (log.getFileExtension().equalsIgnoreCase("xlsx")) {

        label.setIcon((ImageIcon) Pictures.getXlsx());
        label.setText(log.getFileExtension());
    } else if (log.getFileExtension().equalsIgnoreCase("doc")) {
        label.setIcon((ImageIcon) Pictures.getDoc());
        label.setText(log.getFileExtension());
    } else if (log.getFileExtension().equalsIgnoreCase("docx")) {
        label.setIcon((ImageIcon) Pictures.getDoc());
        label.setText(log.getFileExtension());
    } else if (log.getFileExtension().equalsIgnoreCase("pdf")) {
        label.setIcon((ImageIcon) Pictures.getPdf());
        label.setText(log.getFileExtension());
    }

    value = label;
    return label;
}

@Override
public void setHorizontalAlignment(int alignment) {
    super.setHorizontalAlignment(alignment);
}

public void setLog(LogEntry log) {
    this.log = log;
}

}

我在哪里制作模型: (我有很多代码将actionListeners添加到右键单击功能,什么不是 但那几乎没有相关性)

        public void makeLogModel()
 {
    logModel = new DefaultTableModel();

    //addCellEditorListener(this);
    logModel.setColumnIdentifiers(new String[]{"Lavet Dato", "Lavet Af",              "Beskrivelse", "Sidst Redigeret Dato", "Sidst Redigeret Af", "Fil Type"});
    setAutoCreateRowSorter(true);//allows to sort through the information.
    setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    setModel(logModel);
  }

假设发生了魔法(在搜索日志后更新日志表)

     public void updateLogTable(ArrayList<LogEntry> entryList)
 {

        logModel.setRowCount(entryList.size());
        for(int i = 0; i < logModel.getRowCount(); i++)
        {
            setRowHeight(i, 30);
        }
        int row = 0;
        for(LogEntry log : entryList)
        {
            logModel.setValueAt(log.getCreateDate(), row, 0);
            logModel.setValueAt(log.getMadeBy(), row, 1);
            logModel.setValueAt(log.getDescription(), row, 2);
            logModel.setValueAt(log.getLastEdited(), row, 3);
            logModel.setValueAt(log.getLastEditedBy(), row, 4); 
            labelRenderer = new JLabelRenderer(log);
                getColumn("Fil Type").setCellRenderer(labelRenderer);
            logModel.setValueAt(new JLabel(), logRow, 5);   
            row++;
        }
   }    

我已经阅读了组件和编辑器的Java文档 - 但是没有 代码示例适用于JLabel - 可能是因为CellRenderer扩展了JLabel ..

我已经嗅到了getTableCellRendererComponent()方法中'value'参数是应该以某种方式动态设置的信息的信息......任何激增都会很大,请随意提出任何问题。

感谢

2 个答案:

答案 0 :(得分:3)

  

logModel.setValueAt(new JLabel(),logRow,5);

  • 不要将JLabel,任何JComponent放到模型中,XxxTableModel指定为Renderer或Editor的嵌套值,更多内容在Oracle教程中如何使用表 - Creating a Table Model

  • 渲染器或编辑器直观地表示真正的JComponents,更多内容在Oracle教程中如何使用表 - Concepts: Editors and Renderers

  

label.setIcon((ImageIcon)Pictures.getXlsx());

  • 图标应放在局部变量或数组,列表中,无论图标如何,不从Renderer加载任何FileIO,渲染器可以每秒调用多次,例如来自API中的所有鼠标,键和方法

答案 1 :(得分:1)

DefaultTableCellRenderer实施中看似您的问题。

您可以创建JLabelRenderer(LogEntry log)之类的渲染器,因为对于所有单元格,您有一个LogEntry实例,而getTableCellRendererComponent()中的log.getFileExtension()会返回所有行的相同结果。

如果是TableCellRenderer,您需要使用value方法中的getTableCellRendererComponent()参数来确定扩展名和LogEntry实例。

检查Concepts: Editors and Renderers

以下是您的简单示例,我使用的是颜色而不是图标:

import java.awt.Color;
import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;


public class TestFrame extends JFrame{

    public TestFrame(){
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        init();
        pack();
        setVisible(true);
    }

    private void init() {
        JTable table = new JTable(new Object[][]{
                {1,"doc"},
                {2,"xlsx"},
                {3,"abc"}
        },new Object[]{"nmb","extension"});

        table.getColumnModel().getColumn(1).setCellRenderer(getRenderer());
        add(new JScrollPane(table));
    }


    private TableCellRenderer getRenderer() {
        return new DefaultTableCellRenderer(){
            @Override
            public Component getTableCellRendererComponent(JTable table,
                    Object value, boolean isSelected, boolean hasFocus,
                    int row, int column) {
                Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus,row, column);
                if("doc".equals(value)){
                    tableCellRendererComponent.setBackground(Color.YELLOW);
                } else  if("xlsx".equals(value)){
                    tableCellRendererComponent.setBackground(Color.GREEN);
                } else {
                    tableCellRendererComponent.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
                }
                return tableCellRendererComponent;
            }
        };
    }

    public static void main(String... strings) {
        new TestFrame();
    }
}

enter image description here

也不要将Component TableModel logModel.setValueAt(new JLabel(), logRow, 5);放在{{1}}这里{{1}}只是价值。