Poprzednio utworzyliśmy prosty program z interfejsem graficznym utworzonym w Swing’u, korzystając z pomocy NetBeans IDE. Jeśli zaczynasz przygodę ze Swingiem, to warto zacząć od tamtego wpisu.Tym razem utworzymy kolejny prosty program, w którym będziemy mogli otworzyć, edytować i zapisać plik tekstowy. Przy okazji poznamy nowe kontrolki.
Wzorując się na poprzednim wpisie tworzymy nowy projekt, wstawiamy komponent JFrame i umieszczamy w nim JPanel.
Teraz dodajemy do naszego programu kontrolkę umożliwiającą edycję tekstu. Wybieramy z palety kontrolek „Text Area”, umieszczamy go w odpowiednim miejscu i ustawiamy jego rozmiar. Warto także zmienić nazwę komponentu np. na „textArea”.
Rys. 1: Tekst Area
Teraz dodajmy trzy przyciski (kontrolka Button) zmieńmy ich nazwy (buttonOtworz, buttonZapisz, buttonZakończ) a następnie wyświetlalny na nich tekst.
Rys. 2: Główne okno aplikacji
Mamy więc już gotowe główne okno, teraz czas dodać kontrolki które pozwolą otwierać i zapisywać pliki. Pomoże nam w tym kontrolka, która jest odmianą okna dialogowego, o nazwie „File Chooser” (JFileChooser). Znajdujemy ją na palecie i przeciągamy na biały obszar w oknie w którym projektujemy interfejs (obok samego projektu!).
Rys. 3: Wstawianie okienka dialogowego
Teraz zwróć uwagę na okienko nawigatora w lewej dolnej części okna NetBeans IDE.
Rys. 4: Okienko nawigatora
Zauważ, że są tam umieszczone, w sposób hierarchiczny, wszystkie komponenty naszego interfejsu. Klikając na nazwy kontrolek w nawigatorze możemy się łatwo przemieszczać miedzy nimi, co jest szczególnie wygodne gdy chcemy przełączyć podgląd między głównym oknem aplikacji a innymi okienkami, na przykład służącymi otwieraniu i zapisywaniu plików.
Teraz znajduje się tam także JFileChooser o nazwie domyślnej jFileChooser1. Dobrze by było zmienić mu nazwę. Klikamy w nawigatorze na jFileChooser1, a następnie w okienku z właściwościami (prawa, dolna część okna NetBeans IDE) zmieniamy nazwę komponentu. Wybieramy przycisk „Code” w okienku szukamy pozycji „Variable Name” i wprowadzamy nazwę „jFileChooserOtworzPlik”.
Rys. 5: Zmiana nazwy okna otwierania
Klikamy „Properties”, znajdujemy pozycję „dialogType” i upewniamy się, że wybrana jest opcja „OPEN_DIALOG”. Jeśli nie jest, to ustawiamy właśnie taką wartość.
Rys. 6: Właściwości okna otwierania
Mamy już dodaną kontrolkę do otwierania pliku, teraz przydałoby się dodać komponent do zapisywania pliku. Znów wybieramy i dodajemy „File Chooser”, zmieniamy jego nazwę na „jFileChooserZapiszPlik”.
Domyślnie JFileChooser służy otwieraniu plików (opcja „OPEN_DIALOG”) musimy więc zmienić pewne opcje aby go przystosować do zapisu.
W „Properties” szukamy „dialogType” i zmieniamy wartość na „SAVE_DIALOG”. Teraz warto zmienić tekst przycisku zatwierdzenia na „Zapisz”. Zmieniamy więc odpowiednio wartość pola „approveButtonText”.
Rys. 7: Własciwości okna zapisu
Mamy już gotowy interfejs, teraz pozostaje zakodować odpowiednie akcje otwierania i zapisywania pliku oraz zamykania aplikacji.
Szybki podwójny klik na przycisku „Otwórz” (nie na napisie!) przenosi nas do fragmentu kodu odpowiedzialnego za akcję wywoływaną przez kliknięcie przycisku.
Uzupełniamy metodę buttonOtworzActionPerformed
kodem:
int odpowiedz = jFileChooserOtworzPlik.showOpenDialog(this); if (odpowiedz == jFileChooserOtworzPlik.APPROVE_OPTION) { File file = jFileChooserOtworzPlik.getSelectedFile(); try { textArea.read( new FileReader( file.getAbsolutePath() ), null ); } catch (IOException e) { System.out.println("Nie mogę otworzyć pliku: "+file.getAbsolutePath()); System.out.println("Problem: "+e); } }
Podobnie postępujemy z przyciskiem „Zapisz”. W tym przypadku kod wygląda tak:
int odpowiedz = jFileChooserZapiszPlik.showSaveDialog(this); if (odpowiedz == jFileChooserZapiszPlik.APPROVE_OPTION) { File file = jFileChooserZapiszPlik.getSelectedFile(); try { FileWriter out = new FileWriter(file); out.write(textArea.getText()); out.close(); } catch (IOException e) { System.out.println("Nie mogę zapisać pliku: "+file.getAbsolutePath()); System.out.println("Problem: "+e); } }
Uwaga: powyższy, uproszczony sposób zapisywania pliku tekstowego może stwarzać pewne problemy pod Windows (zob. komentarze pod postem). Jak słusznie zasugerował komentator Paweł Słomski, można fragment zapisujący plik zmienić na taki, który będzie bardziej uniwersalny:
FileWriter out = new FileWriter(file); String text = textArea.getText(); out.write(text.replaceAll("\n", System.getProperty("line.separator"))); out.close();
W powyższym kodzie, w 3 linii wszystkie wystąpienia znaku końca linii „\n” są zamieniane na właściwe dla danego systemu operacyjnego, które pobierane są dzięki komendzie System.getProperty("line.separator")
Pozostało jeszcze zaimplementowanie akcji przycisku „Zakończ”. Tu sprawa jest najprostsza:
System.exit(0);
Teraz czas odpalić aplikację. Powinniśmy zobaczyć mniej więcej takie okienko:
Możemy teraz sprawdzić czy można otworzyć plik tekstowy. Po kliknięciu „Otwórz” pokazuje się okienko w którym wybieramy plik do otwarcia.
Rys. 8: Otwieranie pliku
No i proszę:
Rys. 9: Otwarty plik
Teraz możemy zmienić treść tekstu…
Rys. 10: Zmiana treści
Czas sprawdzić czy program zapisuje plik. Klikamy „Zapisz”.
Rys. 11: Zapisywanie pliku
Warto jeszcze sprawdzić, czy plik został zapisany prawidłowo, np. otwierając w dowolnym edytorze tekstu :
Rys. 12: Zapisany plik
Jeszcze pozostało sprawdzić przycisk „Zamknij”…
Bardzo fajny tutorial. Niestety, po zapisaniu pliku i otworzeniu np. w systemowym notatniku nie widać znaków nowej linii. Innymi słowy, wszystko jest w jednej linii. Problem wynika z tego, że windows używa \r\n jako znaku nowej linii, zamiast zwykłego \n.
Cieszę się, że się podoba. Na co dzień nie pracuję pod Windows, ale zdaje się, że notatnik potrafi zrobić takie psikusy. Przypuszczam, że użycie jakiegoś edytora tekstu bardziej przystosowanego do programowania jak np. notepad++ (http://notepad-plus-plus.org), że o NetBeans czy Eclipse nie wspomnę, powinno załatwić sprawę.
Tak, jak napisałeś, notepad++ prezentuje poprawnie sformatowany tekst. Widzę, że pracujesz na Macu, ale tutaj problem również może się pojawić. Znak nowej linii dla Mac OS 9 i wcześniejszych to \r. W Mac OS X jest to standardowy \n.
Moje rozwiązanie sprowadza się do drobnej zmiany przy naciśnięciu buttonZapisz:
FileWriter out = new FileWriter(file);
String text = textArea.getText();
out.write(text.replaceAll("\n", System.getProperty("line.separator")));
out.close();
Tak, to powinno załatwić sprawę, przynajmniej jeśli operujemy w jednym systemie operacyjnym ;-).
Dobrze, że zwróciłeś uwagę na problem.
BTW: Na początku, źle Cię zrozumiałem. Sądziłem że chodzi o plik z kodem.
Stworzyłam prosty edytor tekstowy z menu gdzie moge ustawić kolor czcionki itp. , ale po zapisie i ponownym odczycie tracę wczesniejsze włąsciwości(kolor, rozmiar). Czy koś wie jak się z tym uporać ?
Do niczego ten poradnik i pare innych programy sie nie kompilujac bo brakuje bibliotek i kompilator nie wie co to jest:
BufferedImage
ImageIcon
IOException
NewJFrame itp
Luki jak mowi przyslowie „zlej baletnicy i to i rabke u spodnicy przeszkadza” moze przed buildem i kompilacja upewnij sie ze masz wszystkie imports takie jak import java.io.exception import java.io.file itd bo jak nie to co sie dziwisz?
Lukas, poradniki powinny byc pisane jak dla zielonych, krok po kroku. Jak sam autor napisal na poczatku „Jeśli zaczynasz przygodę ze Swingiem”, „przy okazji poznamy nowe kontrolki”. Sam dopiero zaczalem w javie klikac i bym sie nie domyslil
Rzeczywiście, problemy o których pisał luki przypuszczalnie były spowodowane brakiem zaimportowania odpowiednich bibliotek. Nie wspominam o importowaniu, ponieważ zakładam, że kiedy ktoś zaczyna używać Swing-a to już pewne doświadczenie z programowaniem w Javie ma a jeśli tak, to raczej powinien o tym pamiętać. Zaczynanie przygody z programowaniem od Swinga raczej nie jest dobrym pomysłem. Zauważcie też, że jest tu wiele wpisów dotyczących programowania na różnym stopniu zaawansowania. Byłoby trochę bez sensu, gdybym za każdym razem rozpoczynał od podstaw.
Tak, czy inaczej za uwagi, także krytyczne, dziękuję.