当前位置: 首页 > 知识库问答 >
问题:

JTable中JComboBox的可用性特性

爱刚捷
2023-03-14

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

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

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

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

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

谢谢你的建设性建议。

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个答案

秦伯寅
2023-03-14

这两个问题都可以通过重写DefaultCellEditor#isCellEditable方法并返回true

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

使现代化

简而言之,答案是“一团糟”。长话短说的答案是“非常混乱”

不久前我做了一个“连续编辑”过程。基本上,我覆盖了回车选项卡键绑定。

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

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

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

 类似资料:
  • 问题内容: 我不知道如何在特定行中设置一个jcombobox …现在我已经为所有行设置了这个jcombobox,但是我只希望在一行中设置它: 问题答案: 更新: 在测试我的(可能是不完整的)答案时,我遇到了一个非常好的SO问题,我认为它将比我能提供的更好:将JComboBox放入JTable 另一个更新: 我再次阅读了您的问题,并且意识到您要求输入 特定的行 。我能想到的唯一方法是创建一个自定义C

  • 现在,在第一行第三列(“OK”)中,您可以在JComboBox中选择表示一行的不同条目。因此一行有三个引用另一行的JComboBoxes。如果您在这样的JComboBox中单击,您会注意到它总是选择第一个条目,而不是您在单击之前看到的带有数字的条目。 也许现在你明白我想做什么了?

  • 我创建了一个表单,其中添加了一个,它有3列。第二列和第三列有编辑器。 我希望当我们选择第二列组合框的第一项时,第三列组合框的第一个组合框也应该被选择,反之亦然。 我该怎么做?

  • 好吧,这很难解释,但我会尽力的。 我在JTable中有一个JTextField和一个JComboBox,它的getCellEditor方法被覆盖如下: 以下是行为差异(请注意,从现在开始,当我说JTextField或JComboBox时,我指的是JTable中包含任一组件的单元格): > 当我使用tab键或箭头键导航到JTextField,然后开始键入时,我键入的字符会自动输入单元格。然而,当我以

  • 我正在尝试制作一个JTable,它在一个单元格中有一个JComboBox。我知道我可以使用celleditor,但诀窍是我希望在每一行的组合框中有不同的信息。表中的每一行都代表一个对象,在该对象上有一个arraylist和它的内容,我想在组合框中。到目前为止,这是我的思考过程。 现在,当我稍后调用该方法时(通过按一个按钮),我想插入一个新的行,其中包含Coloum5中唯一的组合框,但我不知道如何做

  • 我有一个JTable对象,我会在一个列上添加5个不同的JComboBox。 我已经尽力了: 但这会将相同的JComboBox添加到该列的所有单元格中。如何在同一列中添加不同的内容? 非常感谢。