2016-11-01 52 views
1

我正在寫一個小程序,它創建一個gui來顯示csv文件的內容。我試着按照Oracle網站(http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data)提供的大綱,但是我的問題是用於構建表的'getColumnCount'方法不能訪問'headers'變量。或者更可能的是,它可以,但是我認爲我在主要方法中所做的更改沒有連接到它。如果任何人都可以解釋出什麼問題以及如何解決問題,那將非常感激。我不確定爲什麼變量不可訪問

public class MyTableModel implements TableModel { 

    private String[] headers;  //This line. 
    private Object[][] tableData; 

    public static void main(String[] args) { 
     String fileName = "products.csv"; 

     String[] csvList = readCSV(fileName); 

     String[] headers = Arrays.copyOfRange(csvList, 0, 10); //Or maybe this line isn't changing the one above. 
    } 

    private static String[] readCSV(String file) { 
     //Some code to fill the list. 
     return fileString; 
    } 

    @Override 
    public int getColumnCount() { 
     return headers.length;  //<<This line of code 
    } 
} 

@Hovercraft全部鰻魚

哦,我應該提到。我正在實現這個類,就是說,我從別處調用它。

private static void createGUI() { 
    csvTabler table = new csvTabler(); 
    table.setTitle("CSV Table"); 
    table.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    table.createJTable(); 
    table.pack(); 
    table.setVisible(true); 
} 

private void createJTable() { 
    jTable = new JTable(new MyTableModel()); 
} 

我敢肯定,這會影響您的解決方案,但我不知道如何調整..

回答

4
String[] headers = Arrays.copyOfRange(csvList, 0, 10); //Or maybe this line isn't changing the one above. 

是的,這就是它概括地說....你」重新嘗試從靜態方法更改實例字段,並且也是隱藏要啓動的變量,而且這不起作用。理解這個變量在主要方法中聲明爲本地這個方法 - 只在方法中可見 - 所以對它的更改對類中的頭實例字段絕對沒有影響。相反,創建一個構造函數,並在需要將其傳遞到類中時傳遞標題數據。

一個壞主意是讓標頭靜態 - 只是不要這樣做,因爲這會拋出OOPs嬰兒洗澡的水,基本上用一個kludge修復你的問題,而不是讓你的程序更清潔更根本性的改進。

例如:

public class MyTableModel implements TableModel { 

    private String[] headers;  //This line. 
    private Object[][] tableData; 


    public MyTableModel(String[] headers, Object[][] tableData) { 
     this.headers = headers; 
     this.tableData = tableData; 
    } 

    @Override 
    public int getColumnCount() { 
     return headers.length;  //<<This line of code 
    } 

    public static void main(String[] args) { 
     String fileName = "products.csv"; 

     String[] csvList = readCSV(fileName); 

     String[] headers = Arrays.copyOfRange(csvList, 0, 10); 
     Object[][] tableData = ..MyTableModel.. // code to create this 

     // now create a table model with your data and use it. 
     MyTableModel myTableModel = new MyTableModel(headers, tableData); 
    } 

    private static String[] readCSV(String file) { 
     String fileString = ""; 
     //Some code to fill the list. 
     return fileString; 
    } 

} 

其他問題:你應該幾乎從來沒有實現的TableModel而是要麼延長或的DefaultTableModel AbstractTableModel上。否則,你的模型將會錯過大部分必要的機器來使其工作。

關於:

,如果我做了什麼實例字段靜態呢?但假設沒有這種簡單的選擇存在。我不打算使用main()方法嗎?我懷疑一個構造函數會更好,但主要方法一開始對測試很有幫助,而且我嘗試構建的構造函數遇到了很多錯誤。

再一次,避免靜態,因爲這增加了代碼的連通性,它的「耦合」沒有益處,這大大增加了隨着程序增長難以發現錯誤的風險。

關於「做我弄死我的主要方法」 - 但當然你的程序將需要一個主要方法地方,所以你已經知道這個問題的答案。主要的方法應該很小,並且應該僅用於設置應用程序的運動部分,而不再是其他部分。

關於「我懷疑一個構造函數會更好,但主要方法對開始測試很有幫助,而且我嘗試構建的構造函數遇到了很多錯誤。」 - 一個構造函數是必要的,主要的方法和構造函數不是相互排斥的,至於錯誤 - 一次只修復一個。

+0

首先,感謝您的回覆!如果我還將實例字段設置爲靜態,那該怎麼辦?但假設沒有這種簡單的選擇存在。我不打算使用main()方法嗎?我懷疑一個構造函數會更好,但主要方法一開始對測試很有幫助,而且我嘗試構建的構造函數遇到了很多錯誤。 –

+0

@AndréFoote:一個非常糟糕的主意。堅持體面的OOPs結構,不要彎曲這個結構來解決你的代碼的根本問題。相反,解決自己的根本問題。請參閱編輯以回答(很快)。 –

+0

請看我在編輯中的問題。 –