0

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

  1. 单元格之间的选项卡应该使 JComboBox 处于活动状态
  2. 单击下拉箭头应立即打开选项列表

关于 1,可编辑组合应将焦点放在嵌入的文本字段内,固定组合应允许向下箭头打开选项列表。

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

为方便起见,我包含了一个清晰的示例,它(我相信)使用推荐的方法在 Jtables 中嵌入 JComboBoxes。

感谢您的建设性建议。

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);
    }
}
4

1 回答 1

3

您的两个问题都可以通过覆盖DefaultCellEditor#isCellEditable方法并返回来解决true

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

更新

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

前段时间我做了一个“连续编辑”过程。基本上,我覆盖了EnterTab键绑定。

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

当我找到一个可编辑的单元格时,我打电话JTable#esitCellAt开始编辑该单元格。

要在单元格开始编辑时使弹出窗口可见,您需要覆盖 and 的addNotify方法JComboBox,使用SwingUtilities#invokeLater,将弹出窗口设置为可见

于 2013-05-05T06:23:00.340 回答