* Работа с файлове в проект с NetBeans
Публикувано на 14 декември 2015 в раздел УКИ.
В това упражнение ще направим връзка между графичната среда Swing и традиционните уроци за работа с файлове. Допълнително ще се запознаем с работа с ListBox. За зареждането на информация от файла ще използваме структура от данни HashMap, но това не е задължително - с малко повече усилия същото може да бъде постигнато с обикновен масив.
В учебната задача имаме даден текстови файл със следната структура:
<име на автор - един ред> <заглавие на произведение - един ред> <текст на произведението - един или повече реда> . <име на автор> т.н.
Както виждате имаме множество произведения на различни автори, които са записани в определен формат. Краят на произведение се намира чрез самостоятелна точка на отделен ред. Един автор може да има повече от едно произведение, като не е задължително произведенията на един автор да са подредени едно след друго.
В задачата се изисква да се направи приложение със Swing, в което на първия екран да се въвежда име на автор. След натискане на бутон "Търси", на втори екран да се заредят произведенията на този автор в ListBox. При натискане върху заглавието на произведение да се зарежда текста му в TextBox.
Решение: Създайте проект AuthorsProject и в него добавете първата (стартова за програмата) JFrame форма, която също наименовайте AuthorsProject и изберете пакет AuthorsProject.
Все още няма да пишем кода за събитието на бутона. Добавете втора JFrame форма - тя ще е следващия екран. Убедете се, че е в същия пакет - в противен случай двете форми няма да се "виждат" една-друга! В тази форма добавете три JLabel и два JScrollPane. Вътре в тези панели добавете един JList и един JTextBox:
Сега трябва да направим така, че при натискане на бутона в първата форма въведения от потребителя текст да бъде прехвърлен във втората форма. Един начин е да използваме вече създадения authorNameLabel. По-универсален вариант (за случаите, в които няма такъв label) е да добавим специална променлива (член-променлива на класа), в която да запишем тази информация. Отидете в Source на AuthorsProjectSecondForm и добавете следния ред непосредствено след дефиницията на класа:
String author;
Екрана с кода би трябвало да изглежда така:
Сега се върнете в първата форма. Добавете ActionEvent за бутона, в който добавете следния код:
// Ако няма въведен текст, няма да правим нищо if(authorName.getText().isEmpty()){ return; } // Създаваме обект за втората форма AuthorsProjectSecondForm sf = new AuthorsProjectSecondForm(); // Записваме името на автора в променливата sf.author = authorName.getText(); // Центрираме новата форма спрямо позицията на текущата sf.setLocationRelativeTo(this); // Визуализираме втората форма sf.setVisible(true); // Скриваме текущата форма this.setVisible(false);
Сега отворете втората форма. В началото добавете DefaultListModel. С обект от този клас ще добавяме елементи в списъка (JList). Добавете и HashMap. С обект от този клас ще добавяме текста на произведението на дадения автор в речник с ключ заглавието на произведението. Повече за речниците прочетете тук. Ще добавим и Scanner, FileReader и IOException - това са обекти, чрез които ще четем от файла. Кодът в началото на файла ще бъде:
import javax.swing.DefaultListModel; import java.util.HashMap; import java.util.Scanner; import java.io.IOException; import java.io.FileReader;
След това добавете два обекта от този клас при член-променливите:
DefaultListModel model = new DefaultListModel(); HashMap<String,String> contents = new HashMap<>();
Би трябвало резултата да е следния:
След това създайте събитие "Window Opened" на JFrame формата.
В неговия код ще инициализираме етикета с името на автора, както и ще заредим произведенията на този автор едновременно в списъка и в речника. Приемаме, че файлът се намира на C:\ и е с име authors.txt. Ако искате изтеглете примерен файл с две произведения на Христо Ботев и две на Петко Славейков.
// Слагаме текста на бутона да бъде // същия като записания в член-променливата authorNameLabel.setText(this.author); // Инициализираме ListBox обекта с новия модел titles.setModel(this.model); // Четем файла и записваме в списъка и в речника try(Scanner s = new Scanner(new FileReader("C:\\authors.txt"))){ // Докато има следващо произведение във файла while(s.hasNext()){ // Четем името на автора String auth = s.nextLine(); // Проверяваме дали е това, което търсим if(auth.equals(this.author)){ String zaglavie = s.nextLine(); // Добавяме заглавието в ListBox чрез model this.model.addElement(zaglavie); // Взимаме текста ред по ред String contentsLines = ""; String line; // Четем до достигането на точка на нов ред while(s.hasNext()){ line = s.nextLine(); if(line.equals(".")) break; else contentsLines+=line+"\n\r"; // \n\r ще обозначи нов ред } // Записваме съдържанието на заглавието в речника this.contentsMap.put(zaglavie, contentsLines); } // В противен случай отиваме на следващ автор else{ String line; while(s.hasNext()){ line = s.nextLine(); if(line.equals(".")) break; } } } } catch(IOException e){ contents.setText("ПРОБЛЕМ С ЧЕТЕНЕТО НА ФАЙЛА"); titles.setEnabled(false); }
Последното, което трябва да направим, е да зареждаме текста на произведението при избор на заглавието. Създайте събитие valueChanged на ListBox обекта:
В него добавете следния код:
String zaglavie = titles.getSelectedValue(); contents.setText(this.contentsMap.get(zaglavie)); // Ако произведението е дълго, връщаме позицията в началото contents.setCaretPosition(0);
С това програмата е завършена.
Добави коментар