1

我所知道的,理论上你可以通过创建 AbstractTableModel 来强制 jTable 不可编辑,并通过始终返回 false 来覆盖以下方法(尽管这不是必需的,因为 AbstractTableModel 的默认方法已经是返回假)。

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

似乎我仍然无法弄清楚如何使这项工作适合我的代码。我究竟做错了什么?这是我的代码:

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class Datagrid extends AbstractTableModel {
    private static final long serialVersionUID = -1080095595481949205L;
    private String[] title;
    private String[][] data;
    private JTable table;
    private JFrame frm;

    public Datagrid(String[] title, String[][] data) {
        this.title = title;
        this.data = data;

        create_table();
    }

    public JTable getTable() {
        return table;
    }

    private void create_table() {
        table = new JTable(data, title);

        frm = new JFrame();
        frm.getContentPane().add(new JScrollPane(table));
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.pack();
        frm.setVisible(true);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    @Override
    public int getColumnCount() {
        return table.getColumnCount();
    }

    @Override
    public int getRowCount() {
        return table.getRowCount();
    }

    @Override
    public Object getValueAt(int row, int column) {
        return table.getValueAt(row, column);
    }

}
4

3 回答 3

3

首先,不要从模型中创建 UI 元素......

其次,不要从 Event Dispatching Thread 之外创建 UI 元素

第三(正如 cubanacan 所指出的),您还没有将模型应用到桌子上......

public static void main(String args[]) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            TableModel model = new Datagrid(); // <-- Create a new instance of the model
            table = new JTable(model);         // <-- Apply it to the table..

            frm = new JFrame();
            frm.getContentPane().add(new JScrollPane(table));
            frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frm.pack();
            frm.setVisible(true);
        }
    });
}

古巴人火了……

第四,以下内容将使您的程序崩溃。这些方法由表调用,以便它了解如何配置自身。

public int getColumnCount() {
    return table.getColumnCount();
}

@Override
public int getRowCount() {
    return table.getRowCount();
}

@Override
public Object getValueAt(int row, int column) {
    return table.getValueAt(row, column);
}

您应该引用您尝试建模的内部数据结构。

您可能会发现通读如何使用表格会有所帮助

于 2012-11-09T08:36:19.963 回答
2
  • 不是答案isCellEditable,从AbstractTableModel

.

public JTable getTable() {
    return table;
}

private void create_table() {
    table = new JTable(data, title);

    frm = new JFrame();
    frm.getContentPane().add(new JScrollPane(table));
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.pack();
    frm.setVisible(true);
}
  • 单独的视图和模型逻辑

  • 以这种形式(缺少addremove行,setValueAt(...))是不可能存储从JTables视图到AbstractTableModel

  • 想念那里ColumnClass

  • s 视图的所有数据JTable都存储在XxxTableModel

  • AbstractTableModel对于 API 中实现的方法(Object[]/ Double[]/ String[]... 和Vector<Object>/ Vector<String>... )非常正确

于 2012-11-09T08:37:56.487 回答
2

你在这里有几个问题:

  1. 您尚未将表模型设置为 JTable。
  2. 如果你设置你的表模型,你会得到StackOverflowError,因为当你调用table.getRowCount()它时,它会调用getModel().getRowCount().
  3. 如果您设置表模型,您将不会获得构造函数中指定的列标题。有关详细信息,请查看方法AbstractTableModel#getColumnName(int)的javadoc 。

这是基于您的代码的可运行且有效的解决方案:

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class Datagrid extends AbstractTableModel {
    private static final long serialVersionUID = -1080095595481949205L;
    private String[] title;
    private String[][] data;
    private JTable table;
    private JFrame frm;

    public Datagrid(String[] title, String[][] data) {
        this.title = title;
        this.data = data;

        create_table();
    }

    public static void main(String[] args) {
        String[] columnTitles = {"Title 1", "Title 2"};
        String[][] tableData = {{"Value 1", "Value 2"}, {"Another Value 1", "Another Value 2"}};
        new Datagrid(columnTitles, tableData);
    }

    public JTable getTable() {
        return table;
    }

    private void create_table() {
        table = new JTable(data, title);
        table.setModel(this);
        frm = new JFrame();
        frm.getContentPane().add(new JScrollPane(table));
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.pack();
        frm.setVisible(true);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    @Override
    public int getColumnCount() {
        return title.length;
    }

    @Override
    public int getRowCount() {
        return data.length;
    }

    @Override
    public Object getValueAt(int row, int column) {
        return data[row][column];
    }

    @Override
    public String getColumnName(int column) {
        return title[column];
    }

}
于 2012-11-09T09:01:07.530 回答