java JComboBox和JTable作为ListCellRenderer组件
我目前正在开发一个JComboBox组件,我希望在一个组合框中有一个JTable用于下拉选择。我已经扩展了ListCellRenderer,并且在弹出窗口中有了表
我想用两种不同的方式来表达它。当弹出窗口不可见时,作为选定行绑定列标签的第一个窗口。第二种方法是在弹出窗口可见时使用JScrollPane显示表
不幸的是,当我这样做时,弹出窗口被缩小到列表的行高,这只为表中的列留出了空间
如果我只是使用滚动窗格,我可以看到完整的表格,但当弹出窗口不可见时,我会看到组合框中的表格,这不是我想要的
如何设置高度,以便在弹出窗口不可见时仍能显示标签的情况下,表格可以容纳
下面是一个编译和运行的简单示例:
import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListCellRenderer;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
public class TableComboBoxMain {
public static void main(String[] args) {
JTableComboBox<Employee> combo = new JTableComboBox<>();
combo.addItem(new Employee("April",3));
//combo.setMaximumRowCount(10);
combo.setRenderer(new TableListCellRenderer(combo));
JFrame frame = new JFrame("Test Table Combo Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(combo);
frame.pack();
frame.setVisible(true);
}
public static class Employee{
String name;
int nr;
public Employee(String name, int number ){
this.name =name;
this.nr = number;
}
}
public static class JTableComboBox<E> extends JComboBox<E> implements ListSelectionListener{
@Override
public void valueChanged(ListSelectionEvent e) {System.out.println("Row selected"+e.getFirstIndex());
this.setSelectedIndex(e.getFirstIndex());
}
}
public static class TableListCellRenderer extends JScrollPane implements ListCellRenderer{
JTable table;
JTableComboBox combo;
boolean mouseListenerAdded;
public TableListCellRenderer(JTableComboBox combo){
this.combo=combo;
DefaultTableModel model = new DefaultTableModel();
String[] cols1 = new String[]{"1","2","3","4"};
String[] cols2 = new String[]{"Mark","John","April","Mary"};
model.addColumn("Nr", cols1);model.addColumn("Name",cols2);
table = new JTable(model);table.setShowGrid(true);table.setGridColor(Color.gray);
this.getViewport().add(table);
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if(!mouseListenerAdded){
list.addMouseListener(this.getListener());
mouseListenerAdded = true;
}//If this is uncommented then the BasicComboPopup size is always no more than 1 row?!!
if(!combo.isPopupVisible()){
Employee emp = (Employee) value;
return new JLabel(emp.name);
}else
return this;
}
public MouseAdapter getListener(){
MouseAdapter adapter = new MouseAdapter(){
@Override
public void mousePressed(MouseEvent e) {
if(combo.isPopupVisible()){
System.out.println("MouseClicked over list");
int row = table.rowAtPoint(e.getPoint());
if(row>0){
table.setRowSelectionInterval(row-1, row-1);
ListDataEvent event = new ListDataEvent(combo,ListDataEvent.CONTENTS_CHANGED,row-1,row-1);
combo.contentsChanged(event);
}
}
}
};
return adapter;
}
}
}
# 1 楼答案
所以我找到了解决问题的办法。我还没有完成,因为我还想进行一些互动:
我想发布解决方案,以防其他人想要一个起点示例。我会在解决这些额外问题时更新我的答案
以下是测试课程:
解决方案的关键部分是,为了在弹出窗口中显示表格和表格的功能,需要覆盖UI。具体来说,您需要覆盖
BasicComboBoxUI
上的createPopup
、getPopupHeightForRowCount
和createScroller
上的BasicComboPopup
。最后,在实现getListCellRenderingComponent
时,您已经设置了一个固定的高度和宽度,与表格首选的高度和宽度相匹配。这将允许弹出窗口的主滚动条充当表格的滚动窗格