Java JComboBox无法在JTable TableHeader中展开

Java JComboBox无法在JTable TableHeader中展开,java,swing,jtable,jcombobox,jtableheader,Java,Swing,Jtable,Jcombobox,Jtableheader,我已经阅读了JTable/JComboBox对这类问题的大部分回答,但还没有找到解决问题的方法 我创建了一个包含JComboBox TableHeader元素的表。JComboBox元素都不会打开以显示项目列表。如何获取要显示的各个JComboBox元素的项目列表 请注意,这个问题的一个区别在于JComboBox位于TableHeader中,而不是嵌入在JTable单元格中 感谢您的帮助 SSCE 导入java.awt.Component; 导入java.awt.Dimension; 导入jav

我已经阅读了JTable/JComboBox对这类问题的大部分回答,但还没有找到解决问题的方法

我创建了一个包含JComboBox TableHeader元素的表。JComboBox元素都不会打开以显示项目列表。如何获取要显示的各个JComboBox元素的项目列表

请注意,这个问题的一个区别在于JComboBox位于TableHeader中,而不是嵌入在JTable单元格中

感谢您的帮助

SSCE

导入java.awt.Component;
导入java.awt.Dimension;
导入java.util.Enumeration;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.ListSelectionModel;
导入javax.swing.SwingUtilities;
导入javax.swing.table.TableCellRenderer;
导入javax.swing.table.TableColumn;
公共类ComboHeaderTest扩展了JScrollPane{
私有静态最终维度默认值_大小=新维度(200200);
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新的ComboHeaderTest().initComponents();
}
});
}
私有ComboHeaderTest(){
最后一个字符串[][]数据={{{“头1”、“头2”、“头3”},
{“A”、“B”、“C”},
{“D”,“E”,“F”},
{“G”、“H”、“I”};
setViewportView(getTable(data));
setPreferredSize(默认大小);
}
私有组件(){
JFrame=新JFrame(“ComboHeaderTest”);
框架。添加(此);
frame.pack();
frame.setVisible(true);
}
私有JTable getTable(最终字符串[][]数据){
最终字符串[]项=数据[0];
final ComboHeaderRenderer[]columnHeaders=新ComboHeaderRenderer[items.length];
对于(int i=0;items.length>i;++i){
columnHeaders[i]=新的ComboHeaderRenderer(项目);
}
最终JTable表=新JTable(数据、列标题);
最终枚举tableEnum=table.getColumnModel().getColumns();
对于(int columnIndex=0;tableEnum.hasMoreElements();++columnIndex){
final TableColumn column=tableEnum.nextElement();
final ComboHeaderRenderer combo=columnHeaders[columnIndex];
column.setHeaderValue(combo.getItemAt(columnIndex));
column.setHeaderRenderer(组合);
}
表.setSelectionMode(ListSelectionModel.SINGLE_选择);
table.setRowSelectionAllowed(真);
table.setColumnSelectionAllowed(false);
table.setCellSelectionEnabled(假);
表.setFillsViewPerthweight(真);
表.设置大小(默认大小);
table.validate();
返回表;
}
私有静态类ComboHeaderRenderer扩展JComboBox实现TableCellRenderer{
公共ComboHeaderRenderer(最终字符串[]项){
对于(int i=0;entries.length>i;++i){
增补(条目[i]);
}
}
@凌驾
公共组件GetTableCellRenderComponent(最终JTable表、最终对象值、,
最终布尔值为选定值,最终布尔值为焦点,最终整型行,最终整型列){
setSelectedItem(值);
归还这个;
}
}
}

这实际上与预期完全一样。我想线索是
TableCellRenderer

渲染器通常是非交互式组件。它们通常只是绘制在表面上的组件的“快照”,用户通常无法与它们交互

这是预期的行为

为了向表格标题提供可编辑的功能,您需要提供一个
JTableHeader

请看下面的一些想法

是一个在JTable表头中使用JComboBox的示例

对于其他类型的组件更容易,请看一看


+1在不必事先询问的情况下包含SSCE。无关:a)b)如果可以通过使用实现相同的目标,请不要扩展JSomething c)setSize要么没有效果,要么你在做一些根本错误的事情(不使用LayoutManager)@kleopatra-正如你所建议的,我更喜欢组合而不是继承。我将此用作测试平台,以发现是什么阻止了JCombox展开,因此没有LayoutManager。只是想在SSCE中保持简单而已。@MadProgrammer-谢谢你为我澄清这一点。我认为渲染器将呈现一个完全功能化的组件,而不仅仅是它的视觉方面。@trashgod-我在发布之前已经看过该项目,但我解释它是基于表格单元格而不是标题提供解决方案,尽管最初的主题是关于标题的。我现在知道我错了。谢谢
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;
    }
}
}