Java JComboBox无法在JTable TableHeader中展开
我已经阅读了JTable/JComboBox对这类问题的大部分回答,但还没有找到解决问题的方法 我创建了一个包含JComboBox TableHeader元素的表。JComboBox元素都不会打开以显示项目列表。如何获取要显示的各个JComboBox元素的项目列表 请注意,这个问题的一个区别在于JComboBox位于TableHeader中,而不是嵌入在JTable单元格中 感谢您的帮助 SSCEJava 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
导入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;
}
}
}