JTable中JComboBox的可用性功能

时间:2013-05-05 03:18:45

标签: java swing jtable jcombobox tablecelleditor

我正在尝试构建一个包含JComboBoxes作为渲染器和编辑器组件的表。这大部分工作正常,但有两件事我似乎无法解决。

  1. 单元格之间的Tab键应该使JComboBox处于活动状态
  2. 点击下拉箭头应立即打开选项列表
  3. 关于1,可编辑的组合应该将焦点放在嵌入的文本字段中,固定的组合应该允许向下箭头打开选项列表。

    关于2,我发现这有时会起作用,这取决于当前其他单元格是否处于活动状态,但有时我必须双击。我无法使这种行为保持一致。

    为方便起见,我提供了一个明确的例子(我相信)使用推荐的方法在Jtables中嵌入JComboBox。

    感谢您提出建设性意见。

    import java.awt.Component;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class TableCombos
    {
        public static void main(String[] args)
        {
            JFrame frame = new JFrame("Frame");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            AbstractTableModel model = new DefaultTableModel()
            {
                String[] columnHeaders = new String[]{"label", "combo-edit", "combo-fixed"};
                Class<?>[] columnClasses = new Class<?>[]{String.class, Double.class, Double.class};
                List<Object[]> data = new ArrayList<>();
                {
                    data.add(new Object[]{"row 1", 1.0d, 2.0d});
                    data.add(new Object[]{"row 2", 2.0d, 3.0d});
                }
    
                @Override
                public int getColumnCount()
                {
                    return columnHeaders.length;
                }
    
                @Override
                public boolean isCellEditable(int row, int column)
                {
                    return column != 0;
                }
    
                @Override
                public int getRowCount()
                {
                    if (data == null) // race condition
                        return 0;
                    return data.size();
                }
    
                @Override
                public Object getValueAt(int row, int column)
                {
                    return data.get(row)[column];
                }
    
                @Override
                public void setValueAt(Object aValue, int row, int column)
                {
                    data.get(row)[column] = aValue;
                }
    
                @Override
                public Class<?> getColumnClass(int column)
                {
                    return columnClasses[column];
                }
    
                @Override
                public String getColumnName(int column)
                {
                    return columnHeaders[column];
                }
            };
    
            JTable table = new JTable(model);
            table.setSurrendersFocusOnKeystroke(true);
    
            TableColumn c1 = table.getColumnModel().getColumn(1);
            TableColumn c2 = table.getColumnModel().getColumn(2);
    
            JComboBox<Double> editorComboEditable = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d});
            editorComboEditable.setEditable(true);
            c1.setCellEditor(new DefaultCellEditor(editorComboEditable));
            c2.setCellEditor(new DefaultCellEditor(new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d})));
    
            final JComboBox<Double> rendererComboEditable = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d});
            rendererComboEditable.setEditable(true);
            final JComboBox<Double> rendererComboFixed = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d});
            c1.setCellRenderer(new TableCellRenderer()
            {
                @Override
                public Component getTableCellRendererComponent(JTable t, Object value, boolean isSelected, boolean hasFocus, int row, int column)
                {
                    rendererComboEditable.setSelectedItem(value);
                    return rendererComboEditable;
                }
            });
            c2.setCellRenderer(new TableCellRenderer()
            {
                @Override
                public Component getTableCellRendererComponent(JTable t, Object value, boolean isSelected, boolean hasFocus, int row, int column)
                {
                    rendererComboFixed.setSelectedItem(value);
                    return rendererComboFixed;
                }
            });
    
            frame.getContentPane().add(new JScrollPane(table));
    
            frame.pack();
            frame.setVisible(true);
        }
    }
    

1 个答案:

答案 0 :(得分:3)

通过覆盖DefaultCellEditor#isCellEditable方法并返回true

来解决您的两个问题

您可能还需要将JTable#setSurrendersFocusOnKeystroke设置为true

<强>更新

简短的回答是“它很乱”。答案很长,“它非常混乱”

我在一段时间后做了“连续编辑”过程。基本上,我覆盖了 Enter Tab 键绑定。

我所做的基本上是停止任何活动的单元格编辑器,记下当前单元格,然后尝试找到下一个可编辑单元格,如果需要,循环回到开始(单元格0x0)。

当我找到一个可编辑的单元格时,我调用了JTable#esitCellAt来开始编辑单元格。

要在单元格开始编辑时显示弹出窗口,您需要覆盖addNotify的{​​{1}}方法,并使用JComboBox将弹出窗口设置为可见