如何让JTable不可编辑

111

如何使JTable变为不可编辑?我不希望用户可以通过双击单元格来编辑其中的值。


1
这里有一个更好的答案:https://dev59.com/uGkw5IYBdhLWcg3waZtW - Paul
7个回答

169

你可以重写isCellEditable方法并按照自己的需求进行实现,例如:

//instance table model
DefaultTableModel tableModel = new DefaultTableModel() {

    @Override
    public boolean isCellEditable(int row, int column) {
       //all cells false
       return false;
    }
};

table.setModel(tableModel);
或者
//instance table model
DefaultTableModel tableModel = new DefaultTableModel() {

   @Override
   public boolean isCellEditable(int row, int column) {
       //Only the third column
       return column == 3;
   }
};

table.setModel(tableModel);

如果您的JTable消失了

如果您在使用此代码时发现JTable消失了,那么很可能是因为您需要使用DefaultTableModel(Object[][] data, Object[] columnNames)构造函数。

//instance table model
DefaultTableModel tableModel = new DefaultTableModel(data, columnNames) {

    @Override
    public boolean isCellEditable(int row, int column) {
       //all cells false
       return false;
    }
};

table.setModel(tableModel);

3
这也是使JTable中的双击事件正常工作的解决方案。双击通常被单元格消耗,并进入编辑模式,这将阻止单元格这样做,而是将双击发送到JTable本身。感谢解决方案,Nelson! - anchorite
2
@Jop 那么你的代码中其他地方肯定有问题——一个表格的模型不可编辑并不会导致表格消失…… - kleopatra
1
@DougHauf 看起来你不太懂Java,或者说并不熟悉大多数语言的布尔运算符号语法...它确实会返回一个布尔值...我建议你去找一些非常基础的Java教程,从头开始学习。试图这样跳入swing将会导致你学习所有的错误知识。 - searchengine27
1
@DougHauf,"=="是Equals函数的别名,用于比较左右两个对象并返回布尔值。我猜你已经使用了if语句来评估布尔值,并且通常与这种表达式一起使用,例如if(a == b)做某事。尝试打印a==b或将其分配给变量并理解结果。 - nelson eldoro
1
上述修复对我也不起作用。它会导致表格的列和数据元素消失。我的表格是通过table = new JTable(tempTable, columnNames)创建的,其中tempTable是一个String[][],Column Names是一个String[]。我认为问题是由于new DefaultTableModel()没有为表格模型指定数据和列名称引起的。如何在数据模型中指定这些内容?我尝试了table.setModel(tableModel(tempTable, columnNames)),但这会导致“找不到符号”错误。 - user1164199
显示剩余2条评论

75
table.setDefaultEditor(Object.class, null);

2
这是最好和最简单的答案。当然,你必须将编辑器设置为 null,这样你就无法编辑它了。 - LEMUEL ADANE
这在单选时非常有效,这正是我要求的。 - Wesos de Queso
这应该是答案! - KrishPrabakar

41
只需添加。
table.setEnabled(false);

对我来说它运行良好。


1
如果您未使用自定义表模型,则这很棒! - Kingsolmn
29
但是你将无法选择单元格或行。 - tianz
3
在某些外观和感觉中,这将呈现为“灰色”。 - jobukkit
2
那很有效。谢谢。不过,我仍然想知道为什么纳尔逊的数据模型方法会导致表格的列和数据元素消失。 - user1164199
1
对我来说很有效! - Colby Cox
显示剩余2条评论

24

1
你不能让一个 public void 方法返回一个布尔值。 - Geo
1
同时,该方法为 isCellEditable - Matt
虽然您指定的方法可行,但是AbstractTableModel中没有isEditable这样的方法。存在的方法是isCellEditable(int,int),它以rowIndex和coulmnIndex作为参数。用户可以通过重写“isCellEditable”方法选择性地启用/禁用特定行/列的编辑,或者可以使用默认实现来禁用所有单元格的编辑。 - sateesh

10

如果您是从一组值自动生成TableModel(使用"new JTable(Vector, Vector)"),也许删除列中的编辑器会更容易:

JTable table = new JTable(my_rows, my_header);

for (int c = 0; c < table.getColumnCount(); c++)
{
    Class<?> col_class = table.getColumnClass(c);
    table.setDefaultEditor(col_class, null);        // remove editor
}

没有编辑器,数据将无法编辑。


5
随意在不适当的地点进行黑客攻击绝不是一种选择。 - kleopatra
请问,为什么这是“在不适当的位置进行随机攻击”?根据setDefaultEditor()文档:“如果编辑器为null,则删除此列类的默认编辑器。” - freesoft
是的,并且回退到Object的默认值;-)因此,您并没有真正禁用编辑(如果其中一个列的类型为Object,则只是意外),而且您可能会错过任何可能具有自定义编辑器的列。确实有API旨在实现控制单元格可编辑性,那就是模型的API。其他所有操作都是黑客行为,因此不适当。 - kleopatra
我理解你的观点。但是我从API中了解到,如果我使用“new JTable(Vector, Vector)”快速创建表格,则该表格将具有所有列的默认编辑器。因此,如果我运行“table.setDefaultEditor(column, null)”,那么我将从该列中删除默认编辑器,因此该列将不具有任何编辑器,并且该列将无法编辑。这样可以吗? - freesoft
这种方法的微调允许按列进行选择性启用/禁用编辑。 - Felype
显示剩余2条评论

3

我使用了这个方法并且它运行良好:非常简单,而且效果很不错。

JTable myTable = new JTable();
myTable.setEnabled(false);

4
无法进行选择。 - h3xStream
简单而美好的解决方案 - Nuwan Harshakumara Piyarathna
1
问题是关于可编辑而不是启用。启用并不能解决问题。 - shaILU

2

创建新的DefaultCellEditor类:

public static class Editor_name extends DefaultCellEditor {
  public Editor_name(JCheckBox checkBox) {
   super(checkBox);
  }
  @Override
  public boolean isCellEditable(EventObject anEvent) {
    return false;
  }
}

并使用setCellEditor:

JTable table = new JTable();
table.getColumn("columnName").setCellEditor(new Editor_name(new JCheckBox()));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接