2016-11-01 2 views
1

저는 csv 파일의 내용을 표시하는 GUI를 만드는 작은 프로그램을 작성하고 있습니다. 나는 오라클 웹 사이트 (http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data)에서 개요를 따라했는데 내 문제는 '헤더'변수에 액세스 할 수없는 테이블을 작성하는 데 사용되는 'getColumnCount'메서드입니다. 아니면 가능할 수도 있지만, 내가 메인 메소드에서 변경했다고 생각한 변경 사항은 연결되지 않았습니다. 누군가가 잘못된 점과 해결 방법을 밝힐 수 있다면 많은 도움이 될 것입니다. 뱀장어변수에 액세스 할 수없는 이유가 확실하지 않습니다.

오의

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. 

그래, .... 당신 ' 다시 정적 필드에서 인스턴스 필드를 변경하려고 시도하고 또한 섀도 잉 변수를 부팅 할 수 있으며 그냥 작동하지 않습니다. 변수가이 메소드에 대해 로컬 (메소드 내에서만 볼 수 있음)이라는 헤더 변수이 선언되어 있으므로 클래스의 헤더 인스턴스 필드에는 변경 사항이 적용되지 않습니다. 대신 생성자를 생성하고 클래스에 전달해야 할 때 헤더 데이터를 전달하십시오.

나쁜 생각은 헤더를 정적으로 만드는 것입니다.이 방법을 사용하면 OOP를 아기가 목욕탕에 버려서 프로그램을 훨씬 더 근본적으로 개선하는 대신 오히려 문제를 해결할 수 있습니다. . 예를 들어

:

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() 메서드를 사용하지 않습니까? 나는 생성자가 더 좋을 것이라고 생각했지만, main 메소드는 처음에는 테스트에 도움이되었고, 생성하려고 시도한 생성자에 많은 오류가 발생했습니다. 이 크게 프로그램이 성장함에 따라 버그를 찾기 어려운의 위험을 증가 혜택없이 코드는 "커플 링"의 연결성을 증가로

다시 정적을 피하십시오.

"내 주요 방법은 없습니까?"물론 프로그램에 기본 방법이 이 필요하므로이 답변을 이미 알고 있습니다. 주요 방법은 작아야하며 움직이는 응용 프로그램 조각 만 설정하면됩니다.

"나는 생성자가 더 좋을 것이라고 생각했지만, 처음에는 테스트에 도움이되었고, 생성하려고했던 생성자에 많은 오류가 발생했습니다." - 생성자가 필요하며, 주 메소드와 생성자는 상호 배타적이지 않으며, 오류에 대해서는 한 번에 하나씩 수정하십시오.

+0

먼저 답장을 보내 주셔서 감사합니다. 인스턴스 필드를 정적으로 만들면 어떻게 될까요? 그러나 그러한 쉬운 옵션이 없다고 가정합니다. main() 메서드를 사용하지 않습니까? 나는 생성자가 더 좋을 것이라고 생각했지만, main 메소드는 처음에는 테스트에 도움이되었고, 생성하려고 시도한 생성자에 많은 오류가 발생했습니다. –

+0

@ AndréFoote : ** 매우 나쁜 아이디어. 괜찮은 OOP 구조를 고수하고 코드에 근본적인 문제를 해결하기 위해이 구조를 구부리지 마십시오. 대신 기본적인 문제 자체를 수정하십시오. 답변을 드릴 편집을 참조하십시오 (곧). –

+0

내 편집 내역을 참조하십시오. –

관련 문제