I have read through the majority of the JTable/JComboBox responses to other questions of this ilk, but haven't yet found a solution to my problem.
I have created a table that has JComboBox TableHeader elements. None of the JComboBox elements will open to display a list of items. How do I get the item lists for the individual JComboBox elements to display?
Please note that a distinguishing element of this question is that the JComboBox is in the TableHeader, not embedded within a JTable cell.
Any help is appreciated.
SSCE
import java.awt.Component;
import java.awt.Dimension;
import java.util.Enumeration;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class ComboHeaderTest extends JScrollPane {
private static final Dimension DEFAULT_SIZE = new Dimension(200, 200);
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new ComboHeaderTest().initComponents();
        }
    });
}
private ComboHeaderTest() {
    final String[][] data = { {"Header 1", "Header 2", "Header 3"},
                                {"A", "B", "C"},
                                {"D", "E", "F"},
                                {"G", "H", "I"}};
    setViewportView(getTable(data));
    setPreferredSize(DEFAULT_SIZE);
}
private void initComponents() {
    JFrame frame = new JFrame("ComboHeaderTest");
    frame.add(this);
    frame.pack();
    frame.setVisible(true);
}
private JTable getTable(final String[][] data) {
    final String[] items = data[0];
    final ComboHeaderRenderer[] columnHeaders = new ComboHeaderRenderer[items.length];
    for(int i = 0; items.length > i; ++i) {
        columnHeaders[i] = new ComboHeaderRenderer(items);
    }
    final JTable table = new JTable(data, columnHeaders);
    final Enumeration<TableColumn> tableEnum = table.getColumnModel().getColumns();
    for (int columnIndex = 0; tableEnum.hasMoreElements(); ++columnIndex) {
        final TableColumn column = tableEnum.nextElement();
        final ComboHeaderRenderer combo = columnHeaders[columnIndex];
        column.setHeaderValue(combo.getItemAt(columnIndex));
        column.setHeaderRenderer(combo);
    }
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    table.setRowSelectionAllowed(true);
    table.setColumnSelectionAllowed(false);
    table.setCellSelectionEnabled(false);
    table.setFillsViewportHeight(true);
    table.setSize(DEFAULT_SIZE);
    table.validate();
    return table;
}
private static class ComboHeaderRenderer extends JComboBox implements TableCellRenderer{
    public ComboHeaderRenderer(final String[] entries) {
        for (int i = 0; entries.length > i; ++i) {
            addItem(entries[i]);
        }
    }
    @Override
    public Component getTableCellRendererComponent(final JTable table, final Object value,
            final boolean isSelected, final boolean hasFocus, final int row, final int column) {
        setSelectedItem(value);
        return this;
    }
}
}
This actually works exactly as expected.  I think the clue is TableCellRenderer.
Renderer's are typically non-interactive components. They are usually just a "snap-shot" of the component painted on to a surface and there is typically no way for a user to interact with them.
This is the expected behavior.
In order to supply editable functionality to the table header, you're going to need to supply your implementation of a JTableHeader
Have a look at this example for some ideas
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With