2012-11-09 123 views
1

我知道理論上你可以通過創建一個AbstractTableModel來強制jTable不可編輯,並且通過始終返回false來覆蓋以下方法(儘管這不是必須的,因爲AbstractTableModel中的默認方法已經返回false)。如何強制jTable不可編輯?

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

} 
+1

1)爲了更好地幫助越早,張貼[SSCCE(http://sscce.org/)(它需要一個'main(String [])'把它放在屏幕上。2)請參閱[使用多個JFrames,好/壞實踐?](http://stackoverflow.com/a/9554657/418556)。特別是,'frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);'會在多次調用create_table()時引發問題。 3)'create_table()'請學習常見的[Java命名約定](http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#73307)(特別是用於名稱)的類,方法和屬性名稱並一致使用它。 –

+1

你還沒有設置表模型到JTable – cubanacan

+0

@cubanacan你應該做出這個答案 – MadProgrammer

回答

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]; 
    } 

} 
+1

刪除從模型 – mKorbel

+0

創建一個GUI好了,我現在要做的是創建一個帶有參數(String [] title,String [] [] data)的TableModel。 另外我會創建一個新的類,它擴展了JTable,我將添加我的附加方法和偵聽器。 最後,我將通過執行以下操作,在我的主課程中調用這兩個: [查看代碼](https://snipt.net/bamboocha/-1155/) - 現在是否正確? :) – bamboocha

+0

@bamboocha是的,它更好,但是你真的不需要擴展'JTable'的類,如果你不打算擴展一些UI功能,監聽器應該進入控制器類。考慮使用[MVC](http://accu.org/index.php/journals/1524)模式。 – cubanacan

3

首先,不要從模型中創建UI元素...

其次重要的是,不要從出方創建UI元素的事件指派線程

三所有的(如苦巴卡斑指出的),你還沒有應用該模型的表...

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

您應該引用您嘗試建模的內部數據結構。

您可能會發現有助於通過How to Use Tables

+0

四個重點:-) – mKorbel

+0

太好了,謝謝!似乎我剛剛開始意識到如何做這件事情.. – bamboocha

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

  • JTable的觀點的所有數據都存儲在XxxTableModel

  • quite correct AbstractTableModel在API實現的方法(Object[]/Double[]/String[] ......和Vector<Object>/Vector<String> ...)

+0

首先:謝謝!更改我的表是不必要的,因爲我只需要顯示從我的數據庫中檢索到的數據。同樣適用於ColumnClass。爲什麼我應該實施它們? – bamboocha

+0

來檢查我的答案中鏈接的代碼getColumnClass() – mKorbel