0

To put this short:

What is this about

I have a JTable with Model which displays data fetched from an SAP system. My Goal is in a specific column to display only a part of the data which is in the model. For example the row of the model has Object["a","b"] but the user is only supposed to see a.

So I read a lot of threads here on StackOverflow and a lot of tutorials on how to use custom tablecellrenderers and editors etc. but I am not able to fix my problem, which is that the cell where i registered the renderer will not be highlighted when selected. A possible solution is described HERE but this does not work for me.

Here is my custom Renderer:

public class SapChangeNumberCellRenderer extends DefaultTableCellRenderer{

private static final long serialVersionUID = -2649719064483586819L;

private SapChangeNumberTable table;
private int valuesSize;

public final static String ASM_AMOUNT = LanguageServer.getString("71", "Baugruppen");

public SapChangeNumberCellRenderer(SapChangeNumberTable table) {
    super();
    this.table = table;
}


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

    // components & Layout
    JPanel panel = new JPanel(new BorderLayout());
    JButton buttonDots = new JButton("...");
    JLabel text = new JLabel();

    List<String> values = (List<String>) value;
    valuesSize = values.size();
    if (valuesSize > 0) {
        // set values
        buttonDots.setPreferredSize(new Dimension(14, 14));
        text.setText(values.get(0));
    } else {
        text.setText("");
    }

    if (valuesSize > 1) {
        // button to open dialog only if we have more than 1 item
        panel.add(buttonDots, BorderLayout.EAST);
    }

    panel.add(text, BorderLayout.WEST);
    panel.setOpaque(true);
    return panel;
}

@Override
public String getToolTipText(MouseEvent e) {
    String toolTip = String.valueOf(valuesSize) + Initializer.SPACE + ASM_AMOUNT;

    return toolTip;
}

public SapChangeNumberTable getTable() {
    return table;
}
}

So as you can see depending on the list size of the values I manipulate the component which will be given back from the method. The setOpaque(true) method does somehow not achieve my goal.

Here is the according JTabel (note: BaseTable is just a wrapper for JTable with some goodies I need...nothing fancy here)

public class SapChangeNumberTable extends BaseTable {

/** the model */
private SapChangeNumberTableModel model = new SapChangeNumberTableModel();

/** parent frame */
private SapPanel parent = null;

public SapChangeNumberTable(SapPanel parent) {
    this.parent = parent;
    this.init();
}

/**
 * init the table
 */
private void init() {

    // set model (not filled yet)
    this.setModel(model);

    // set renderer
    setRendererAndEditor();

    // add search filter row, enabling sorting is included
    this.addFilterSearchRowPanel();
    // single selection
    this.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    // hide
    this.hideColumns();
    this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}

/**
 * sets the default table cell renderer
 */
private void setRendererAndEditor() {
    getColumnModel().getColumn(convertColumnIndexToView(SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER))
            .setCellRenderer(new SapChangeNumberCellRenderer(this));
    getColumnModel().getColumn(convertColumnIndexToView(SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER))
            .setCellEditor(new SapChangeNumberAsmRefTableCellEditor(this));
}

@Override
public void setStatusBarDataCount(boolean value) {
}

@Override
public void hideColumns() {
}

@Override
public int getColModelSortIndex() {
    return 0;
}

@Override
public void load() {
}

@Override
public SapChangeNumberTableModel getModel() {
    return model;
}

public boolean isChanging() {
    return model.isFilling();
}

public SapFactoryChange getRow(int row) {
    return model.getSapFactoryChange(row);
}

@Override
public void clear() {
    model.clear();
}

@Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
    Component comp = super.prepareRenderer(renderer, rowIndex, vColIndex);

    if (vColIndex == SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER) {
         //what the hack to do here to manipulate the comp ? I can't add a JPanel to a plain Component
    }

    return comp;
}

}

In the table I tried some stuff with prepareRenderer but here I can't manipulate the data (values) and all other stuff I am doing in the custom renderer. Maybe I have a basic understanding problem of how to approach this. I am thankful for any hints !

Community
  • 1
  • 1
m0rb
  • 63
  • 10

1 Answers1

0

I just found a very simple solution which I thought would overwrite my wanted behavior, but it doesn't.

Just implemented this into the Table:

@Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
    Component comp = super.prepareRenderer(renderer, rowIndex, vColIndex);

    if (isRowSelected(rowIndex)) {
        comp.setBackground(Color.ORANGE);
    }

    return comp;
}

works like a charme!

m0rb
  • 63
  • 10
  • to be added: I still have a custom renderer set to this table cell and it behaves as expected ! – m0rb Sep 14 '16 at 08:16