2016-11-01 6 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 Full Of Угри

О, я хотел бы упомянуть. Я реализую этот класс, как это, то есть я называю его из другого места.

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. 

Да, это в двух словах .... вы» re пытается изменить поле экземпляра из статического метода, а также shadowing переменная для загрузки, и это просто не сработает. Поймите, что переменная заголовков объявила в основном методе local к этому методу - видимо только внутри метода - и поэтому изменения в нем не будут иметь абсолютно никакого эффекта на поле экземпляра заголовков в классе. Вместо этого создайте конструктор и передайте данные заголовка, когда вам нужно передать его в класс.

Плохая идея состоит в том, чтобы сделать заголовки статическими - просто не делайте этого, так как это выбрасывает ребенка ООП с водой для ванны, по существу устраняя вашу проблему с помощью 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: ** очень ** плохая идея. Придерживайтесь достойной структуры OOP и не сгибайте эту структуру, чтобы исправить фундаментальную проблему с вашим кодом. Вместо этого исправьте основную проблему. См. Правки для ответа (скоро). –

+0

см. Мое редактирование в вопросе. –

Смежные вопросы