【发布时间】:2017-10-05 06:37:44
【问题描述】:
我目前正在开发一个 JComboBox 组件,我希望在 ComboBox 内部有一个 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;
}
}
}
【问题讨论】:
-
非常感谢您的参考!不幸的是,在过去的几周里,我仔细研究了这两个。我一直在左右创建渲染器。这是我唯一无法解决的问题。查看库,这似乎是因为列表行高我无法控制我所看到的。我可以设置可见行的 nr,但我无法触摸由列表单元格渲染器中的项目确定的行高。不过再次感谢!
标签: java swing jtable jcombobox tablecelleditor