Q-Tenberga>> Lekcja 5
|
Lekcja 5: Bufory |
|
|
|
Lekcja 5 dogłębnie omawia ideę i zastosowanie buforów, które łączą kod programu z elementami wydruku.
|
Wydruk składa się z dwóch zasadniczych części: ustawienia elementów graficznych oraz programu dostarczającego danych. Części te są od siebie mocno niezależne i będą omówione oddzielnie. Synchronizacją obu tych części zajmuje się specjalny algorytm [FillMachine.java], który pilnuje, aby w odpowiednim momencie przechodzić do dalszej części ustawienia i odpowiednio łamać je na strony.
Aby program qvl mógł sterować zawartością wydruku, musi mieć jakieś miejsce do wkładania preparowanych przez siebie danych. Służą do tego bufory. Prawie każdy element ustawienia ma swój bufor, a niektóre z nich nawet kilka (np tabela ma oddzielne bufory dla nagłówka, ciała i stopki, a także dla każdej linii.) Oczywiście nie musimy używać wszystkich buforów, tylko te, które akurat są nam potrzebne. Bufory ustawione są w drzewa, których hierarchia odpowiada hierarchii elementów ustawienia - czyli bufory tabelki zawierają bufory jej komórek etc.
Najlepiej zademonstruje nam to prosty przykład (TRZEBA GO ZROZUMIEĆ!)


Podgląd buforów w programie przedstawi nam to drzewo w nieco mniej przyjemny sposób. Wyglądać ono będzie następująco:

W rzeczywistości wszystkie bufory całego wydruku ułożone są w jedno duże drzewo. Jego wierzchołek nazywa się mainBuf.

Na buforach możemy wykonać cztery zasadnicze operacje w programie QVL:
Buffer getBuffer(String name)zwraca nam bufer-dziecko o podanej nazwie. W powyższym przykładzie mając na zmiennej t bufor TAB możemy otrzymać bufor tekstu w pierwszej komórce wywołując:
Buffer text = t.getBuffer("HEAD").getBuffer("LINE1").getBuffer("CELL").getBuffer("TEXT")
możemy to samo też wywołać skrótowo:
Buffer text = t.getBuffer("HEAD.LINE1.CELL.TEXT")
void set(Object val)operacja ustawienia bufora - przykład:
text.set("Hello world");
void fix()operacja zafiksowania wartości w buforze - oznacza to, że wartość jaka już jest, jest ostateczna. (Przekłada się to np. na żądanie nowej linii tabeli)
void put(Object val)jest to podstawowa operacja wrzucenia do bufora - w rzeczywistości złożenie set i fix.
Ponadto niektóre bufory udostępniają dodatkowe metody:
void putLine(Record r)metoda powoduje wrzucenie do tabelki jako linii całego rekordu - działa tak, że szuka w tabelce buforów nazywających się tak, jak pola rekordu i jeżeli znajdzie, to wrzuca za pomocą put.
void goTo()wywołanie tej metody powoduje przejście do tego fragmentu. Pozwala to wymusić inną kolejność drukowania fragmentów niż wyznaczona przez Algorytm synchronizacji. W szczególności pozwala to wracać do raz wydrukowanego fragmentu kilka razy.
Jak wykazała praktyka, pisanie wyciąganie konretnego buforu poprzez pisanie
pełnej ścieżki dostępu (np."S.F.TAB.BODY.LINE1.CELL_1.TAB.HEAD.LINE1.TEXT") bywało dość uciążliwe.
Aby ułatwić życie powstał mechanizm skrótów w wołaniu buforów. Otóż podaną powyżej ścieżkę można
skrócić poprzez wyrzucenie dowolnych węzłów ze środka, o ile powstały w ten sposób skrót
będzie jednoznacznie identyfikował tą ścieżkę. (czyli gdy nie istnieje inna ścieżka o takim samym skrócie).
Zobaczmy to na rysunku poglądowym:


W praktyce dobrze jest przemianować używane bufory typu TEXT, aby móc bezpośrednio się do nich odwoływać:
