Question

im been looking around on the internet for about 5 hours now to debug on this issue ive been having. and Basically i haven't been able to find anywhere where a person tries to add a new JLabel for each row in a specific column.

functionality explanation: i get a file url, i take the postFix which is usually xlsx or doc - this postfix i want to display in a JLabel in coalition with a Excel or Doc Icon -.- but what my current code does is just paint the same JLabel over and over again because it only sets the CellRenderer one time and uses it on all the rows dispite the fact that im setting it in a for-loop for each iteration - all my code is correct for this functionality up until the renderer only gets called once.

so my question goes as follows - how do i add a new JLabel for each row in a Column ? -

my code follows.

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

}

where i make my model: (i have alot more code adding actionListeners to right-click functionality and what not but thats hardly relevant)

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

Where the magic was suppose to happen(update the log table after a search on logs)

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

i have read the Java documentation for components and Editors- but none of the code examples are for a JLabel - probably because CellRenderer extends JLabel..

i have allso sniffed up the info that the 'value' parameter in the getTableCellRendererComponent() method is the one that is supposed to be set dynamically somehow... any surgestions would be greatly apriciatet, feel free to ask any questions.

thanks

Was it helpful?

Solution 2

Seems your problem in DefaultTableCellRenderer implementation.

You create renderer like JLabelRenderer(LogEntry log) because of, for all cells you have one instance of LogEntry, and log.getFileExtension() in getTableCellRendererComponent() returns same result for all rows.

In case of TableCellRenderer you need to use value parametr from getTableCellRendererComponent() method to determine extension and LogEntry instance.

Examine Concepts: Editors and Renderers.

Here is simple example for you, I use color instead of icons:

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

Also don't put Component's to TableModel like here logModel.setValueAt(new JLabel(), logRow, 5); just value.

OTHER TIPS

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

  • don't put JLabel, any JComponent to the model, XxxTableModel is designated to nest value for Renderer or Editor only, more in Oracle tutorial How to use Tables - Creating a Table Model

  • Renderer or Editor visually represents real JComponents, more in Oracle tutorial How to use Tables - Concepts: Editors and Renderers

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

  • Icon should be placed into local variables or array, list, whatever of Icons, don't load any FileIO from Renderer, renderer can be called many times per one second, e.g. from all mouse, keys and methods inplemented in APIs
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top