Drzewa

 

XUL umożliwia tworzenie tabelarycznych lub hierarchicznych list przy użyciu drzewa.

Drzewo

Drzewo w XUL jest jednym z najbardziej złożonych elementów. Drzewo może być użyte w celu wyświetlenia wierszy tekstu w kolumnach, na liście lub hierarchicznie. Drzewo umożliwia zmiany wyglądu, rozmiaru czy ukrywanie poszczególnych kolumn. Przykładami drzew są między innymi te zawierające listę wiadomości w programie pocztowym lub w okno zakładek w Mozilli.

W wielu sytuacjach drzewo posiada wiele wspólnych cech z polami listy (listbox). Oba mogą być użyte do utworzenia tabel z danymi, zawierających wiele wierszy i kolumn oraz nagłówków. Jednak drzewa umożliwiają zagnieżdżanie wierszy, czego nie umożliwiają pola list. Przewagą pól list jest to, że można w nich zawrzeć dowolny typ zawartości, podczas gdy drzewa mogą zawierać tylko obrazy i tekst (stosując zaawansowane możliwości, możemy dodać do drzewa paski postępu lub pola wyboru).

Drzewo składa się z dwóch części, ciała drzewa i ustawienia kolumn:

  • Zestawu kolumn, który jest zdefiniowany przez pewną liczbę elementów treecol, po jednym na każdą kolumnę. Każda kolumna będzie widoczna w postaci nagłówka na szczycie drzewa.
  • Druga cześć, ciało drzewa (tree body), które zawiera dane ukazujące się w drzewie i jest ono tworzone przy użyciu znacznika treechildren.

Drzewo jest wyjątkowym elementem. Ciało drzewa składa się z pojedynczego widgetu, który wyświetla wszystkie dane w drzewie. To kontrastuje z polem listy, gdzie pojedynczy znacznik listitem i listcell jest stosowany by wyszczególnić wiersze w polu listy. W drzewie wszelkie dane do wyświetlenia są dostarczane przez oddzielny obiekt zwany widokiem drzewa. Gdy przyjdzie kolej na pokazanie komórki, widget drzewa określi, co jest do wyświetlenia i wyśle taką informację do widoku drzewa, co następnie będzie wyświetlone przez drzewo. Drzewo jest zdolne do tego, by wyciągać informacje z widoku, które wiersze mają być wyświetlone. To umożliwia optymalizację widoku w taki sposób, by pobierał informacje tylko o tym, co ma być wyświetlone. Dla przykładu, drzewo może mieć tysiące wierszy, dodatkowo większość z nich rozwiniętych poza granice widoku, tak że nie są widoczne. To znaczy, że drzewo jest skalowalne do dowolnych rozmiarów bez problemów z wydajnością.

Widok drzewa jest obiektem implementującym interfejs nsITreeView. Interfejs ten zawiera trzydzieści własności i funkcji, które można zaimplementować. Funkcje te będą wywoływane przez drzewo zawsze, kiedy będzie konieczne uzyskać dane o stanie drzewa. Na przykład funkcja getCellText() będzie wywoływana w celu pobrania etykiety dla konkretnej komórki drzewa.

Korzyścią z używania widoku jest w pewnym stopniu możliwość przechowywania w widoku danych w sposób dla nich odpowiedniejszy lub ładowania danych na żądanie (tak jak wiersze są wyświetlane). To umożliwia uzyskanie większej elastyczności podczas używania drzew.

Naturalnie, próba implementacji widoku drzewa z trzydziestoma lub więcej własnościami i metodami może być bardzo niewygodna, w szczególności dla prostych drzew. Na szczęście XUL dostarcza kilka wbudowanych rozwiązań, które wykonają najtrudniejsze zadania za Ciebie. Dla większości drzew (szczególnie, gdy zaczynasz prace z drzewami), możesz użyć jednego z gotowych, wbudowanych typów. Jednak nic nie stoi na przeszkodzie, aby utworzyć całkowicie nowy wygląd. Jeżeli chcesz możesz przechowywać dane w tablicy lub w strukturze danych JavaScriptarray, bądź wczytywać dane z pliku XML.

Ponieważ całe ciało drzewa to pojedynczy widget, nie można zmienić stylu podanego wiersza lub komórki normalną drogą dlatego, że nie ma tam elementów, które wyświetlają pojedyncze komórki, jak to ma miejsce przy listbox. Zamiast tego całość jest rysowana przez ciało drzewa przy użyciu danych dostarczanych przez widok. To jest ważny punkt i wielu programistów XUL ma problem w zrozumieniu tego aspektu. By zmodyfikować wygląd pojawiającej się komórki, widok musi połączyć zestaw słów kluczowych dla wiersza i komórki. Używana jest specjalna składnia CSS. W pewien sposób to wygląda jak używanie klas CSS. Stylizacja drzew będzie omówiona bardziej szczegółowo nieco później.

Elementy drzewa

Drzewa mogą być tworzone przy użyciu elementów tree, które są opisane w następnych artykułach. Są też tam dwa elementy używane przy definiowaniu kolumn, które są wyświetlone w drzewie.

tree
Zewnętrzny element drzewa.
treecols
Element wypełniający zestaw treecol.
treecol
Jest używany do deklarowania pojedynczej kolumny drzewa. Używając tego elementu, można określić dodatkową informację o tym, jak dane w kolumnach maja być posortowane, a także czy użytkownik może zmieniać rozmiar kolumn. Zawsze powinno się umieszczać atrybut id na kolumnie. Mozilla stosuje id do identyfikacji kolumn przy ich ponownej aranżacji lub ich ukrywaniu. Od wersji 1.8 Mozilla już tego nie wymaga, jednak mimo wszystko dobrze jest używać atrybutu id do oznaczania kolumn.
treechildren
Zawiera główne ciało drzewa, w którym są wyświetlane pojedyncze wiersze danych.
Przykład drzewa z dwoma kolumnami

Źródła Podgląd

<tree flex="1">

  <treecols>
    <treecol id="nameColumn" label="Nazwa" flex="1"/>
    <treecol id="addressColumn" label="Adres" flex="2"/>
  </treecols>

  <treechildren/>

</tree>

Cała tabela otoczona elementem tree. To deklaruje element, który jest użyty jako tabela lub drzewo. Podobnie jak z tabelami HTML, dane w drzewie są zorganizowane w wierszach. Kolumny są określone przy pomocy znacznika treecols.

W drzewie możesz umieścić tyle kolumn ile sobie życzysz. Tak jak w przypadku listy pól, wiersz nagłówka pojawia się wraz z etykietami kolumn na samej górze. Rozwijane menu ukazuje się w prawym górnym rogu drzewa. Użytkownik może go używać do ukrywania i wyświetlania wybranych kolumn. Każda kolumna jest utworzona przy pomocy elementu treecol. Możesz ustawić etykietę używając jej atrybutu label. Możesz stworzyć elastyczne kolumny, jeśli drzewo będzie elastyczne, to pozwoli ono zmieniać szerokości kolumn. W tym przykładzie druga kolumna jest dwa razy szersza do pierwszej. Wszystkie kolumny powinny być umieszczone wewnątrz elementu treecols.

W tym przypadku nie określiliśmy widoku w celu dostarczeniu danych drzewa, więc zobaczymy tylko nagłówki kolumn i puste ciało drzewa. Można zmieniać rozmiar okna dopóki nie ma tam żadnych danych do wyświetlenia. Dopóki drzewo było oznaczone jako elastyczne, ciało rozciągało się na całej dostępnej powierzchni. Czyniąc drzewo elastycznym, jak to się zwykle robi, pokazywane są tylko najbardziej istotne dane, więc drzewo jest tak rozciągane, żeby je dopasować. Jednak można wyszczególnić pewną liczbę wierszy (rows) do pokazania w drzewie (tree) przez umieszczenie rzędów w atrybucie elementu. Atrybut ten określa jak wiele wierszy jest wyświetlanych w interfejsie użytkownika, a nie ile wierszy tam się znajduje. Całkowita liczba rows jest dostarczana przez widok drzewa. Jeżeli w drzewie znajduje się więcej wierszy, przejrzenie pozostałych umożliwia pasek przewijania. Jeżeli nie nadasz atrybutowi rows wartości 0, znaczy to, że żaden z wierszy się nie pojawi. W tym przypadku można by zrobić drzewo elastyczne, jeżeli tak uczyniłeś to nie będzie potrzebny atrybut rows, ponieważ urośnie on do maksymalnej dostępnej powierzchni.

Treść widoku drzewa

Mówiliśmy, że dane, by być pokazanymi w drzewie, pochodzą z widoku, a nie ze znaczników XUL, zdarza się, że wbudowany widok drzewa otrzymuje dane właśnie ze znaczników XUL. To może być nieco mylące, ale zasadniczo jeden z wbudowanych widoków drzewa używa zestawu znaczników, które mogą być zastosowane do określenia informacji na temat danych w drzewie. Następujące znaczniki są używane:

treeitem
Zawiera pojedynczy górny poziom wiersza i jego pochodne. Element ten służy także jako element, który może być wybrany przez użytkownika. Znacznik treeitem powinien być umieszczony dookoła wiersza, tak, że może być wybrany jako całość.
treerow
Pojedynczy rząd drzewa, który powinien być umieszczony wewnątrz znacznika treeitem.
treecell
Pojedyncza komórka drzewa. Winien być umieszczony wewnątrz elementu treerow.

Znaczniki te powinny być umieszczone bezpośrednio wewnątrz znacznika treechildren, zagnieżdżone powyżej. Znaczniki definiują dane do umieszczenia w ciele drzewa. W tym przypadku drzewo używa wbudowanego widoku drzewa, zwanego treścią widoku drzewa, który używa etykiet i wartości określonych w tych elementach jako dane dla drzewa. Kiedy drzewo wymaga wyświetlenia wiersza, drzewo zażąda etykietę komórki, od okna widoku używając widoku funkcji getCellText, która otrzymuje dane od etykiety odpowiedniego elementu treecell.

Jednak są tam trzy wylistowane elementy, które nie są bezpośrednio pokazywane. Są używane jako źródło danych widoku. Są garścią atrybutów dodawanych do elementu treeitem i powiązanych elementów. Na przykład, nie możesz zmienić wyglądu pojawiających się wierszy drzewa stosując atrybuty style, albo z innymi własnościami CSS i odpowiednio powiązanymi cechami, takimi jak elastyczność i orientacja.

Faktycznie, oprócz kilku specyficznych atrybutów drzewa, tylko atrybuty, które będą przynosiły jakikolwiek efekt, będą atrybutem tekstu etykiety ustawianym przez label dla komórki i src w celu umieszczeniu i obrazu. Są jednak specjalne sposoby tytułowania drzewa i umieszczania innych cech, które zobaczymy w kolejnych artykułach.

Zdarzenia nie są wysyłane do elementu treeitem i ich dzieci, zamiast tego są wysyłane do elementu treechildren.

Jako że pozycje drzewa są niepodobne do elementów XUL, są one źródłem wspólnych nieporozumień dla programistów XUL. Widok drzewa treści widoku jest widoczny tam, gdzie dane dla komórek są dostarczone do znaczników umieszczonych wewnątrz drzewa. Naturalnie, jeżeli używasz widoku innego rodzaju, dane będą dostarczone z innego źródła i nie będzie tam żadnych elementów treeitem.

Zobaczmy, jak utworzyć proste drzewo z wieloma kolumnami używając treści widoku drzewa. Można tego użyć do stworzenia listy wiadomości e-mail. Może się tam znaleźć wiele kolumn, takich jak nadawca i temat.

Przykład drzewa z treechildren

Źródła Podgląd

grafika:trees1.png
<tree flex="1">

  <treecols>
    <treecol id="sender" label="Nadawca" flex="1"/>
    <treecol id="subject" label="Temat" flex="2"/>
  </treecols>

  <treechildren>
    <treeitem>
      <treerow>
        <treecell label="joe@somewhere.com"/>
        <treecell label="Ściśle tajne plany"/>
      </treerow>
    </treeitem>
    <treeitem>
      <treerow>
        <treecell label="mel@whereever.com"/>
        <treecell label="Zróbmy obiad"/>
      </treerow>
    </treeitem>
  </treechildren>

</tree>

Jak widać na obrazku, drzewo zostało utworzone z dwoma wierszami danych.

Drzewo to ma dwie kolumny, z których druga zajmie więcej miejsca niż ta pierwsza. Zazwyczaj będziemy tworzyć elastyczne kolumny. Możemy także dostarczyć informację o szerokościach za pomocą atrybutu width. Powinno się zawrzeć taką samą liczbę elementów treecol, ile jest kolumn w drzewie. W przeciwnym przypadku może to powodować powstawanie dziwnych, nieoczekiwanych sytuacji.

Wiersz nagłówka jest tworzony automatycznie. Przycisk w prawym górnym rogu może być użyty w celu ukrycia i pokazania kolumn. Można umieścić atrybut hidecolumnpicker w drzewie i ustawić go jako true w celu ukrycia tego przycisku. Jeżeli przycisk zostanie tak ukryty, użytkownik nie będzie miał możliwości chowania kolumn.

Można być pewnym, że ustawiony atrybut id przy każdej kolumnie, albo ukrywanie i pokazywanie kolumn nie będzie pracować z wszystkimi wersjami przeglądarki Mozilla.

Element treechildren otacza wszystkie wiersze. Wewnątrz ciała są wiersze, które mogą z kolei zawierać kolejne wiersze. Dla prostszego drzewa każdy wiersz jest tworzony przez treeitem i treerow. Element treerow otacza wszystkie komórki w pojedynczym wierszu, podczas gdy element treeitem otaczałby wiersz i wszystkie jego dzieci. Drzewa z zagnieżdżonymi wierszami są opisane w następnym artykule.

Wewnątrz wierszy możemy umieścić pojedyncze komórki drzewa. Te są tworzone przy użyciu elementu treecell. Można umieścić tekst komórki używając atrybutu label. Pierwszy treecell w wierszu określa zawartość, która ukaże się w pierwszej kolumnie, drugi treecell określa zawartość drugiej kolumny itd.

Użytkownik może wybrać pozycje drzewa klikając na nie myszką lub podświetlając je przy życiu klawiatury. Można wybierać wiele pozycji na raz, przytrzymując klawisz SHIFT lub CTRL, a następnie klikając w kolejny wiersz, jaki chcemy zaznaczyć. W celu uniemożliwienia wielokrotnego zaznaczenia (wyboru), należy umieścić atrybut seltype w drzewie i ustawić jego wartość na single. Dzięki temu użytkownik może dokonać zaznaczenia (wyboru) tylko jednej pozycji w danym momencie.

Dodajemy drzewo do przykładu Znajdź pliki

Dodajemy drzewo do okna wyszukiwania plików, gdzie są wyświetlane wyniki. Drzewo użyje treści widoku drzewa. Następujący kod powinien zająć miejsce iframe.

<tree flex="1">   <treecols>     <treecol id="name" label="Nazwa pliku" flex="1"/>     <treecol id="location" label="Lokalizacja" flex="2"/>     <treecol id="size" label="Rozmiar" flex="1"/>   </treecols>    <treechildren>    <treeitem>      <treerow>        <treecell label="mozilla"/>        <treecell label="/usr/local"/>        <treecell label="2520 bajtów"/>      </treerow>    </treeitem>   </treechildren> </tree>

<splitter collapse="before" resizeafter="grow"/>

Dodaliśmy drzewo z trzema kolumnami dla nazwy pliku, lokalizacji i rozmiaru. Druga kolumna będzie dwa razy szersza z powodu większej elastyczności. Pojedynczy wiersz został dodany, by zobrazować, jak wygląda tabela z wierszem. W rzeczywistości, wiersze byłby dodane przez skrypt zależnie od wyników wyszukiwania lub byłby stworzony własny widok do przetrzymania danych.

Przykład Znajdź pliki: Źródła Podgląd

Następnie nauczymy się, jak stworzyć bardziej zaawansowane drzewa.

Tłumaczenie: PHP.pl

 

Autorzy i etykiety dokumentu

Etykiety: 
Contributors to this page: teoli, fscholz, Witia, Mgjbot, Ptak82, Antisocial, Nickolay
Ostatnia aktualizacja: teoli,