JSF 2.0 dataTables

azenth

Mitglied
Hallo Java-Community,

ich habe ein Problem mit dataTables. Eventuell ist es auch für einen totalen Anfänger auch einfach noch zu kompleziert.

Mein Problem:

Ich bekomme von meinem Controller die Listen zurück, einmal eine UserListe und einmal eine HostListe.

Wenn ich das wie folgt mache, dann funktioniert das sehr gut.

Code:
<h1>Host Groups</h1>
<h:dataTable value="#{userControler.ugroups}" var="ugrp">
   <h:column>
      <h:outputText value="#{ugrp.name}"/>
   </h:column>
</h:dataTable>
<h1>Host Groups</h1>
<h:dataTable value="#{userControler.hgroups}" var="hgrp">
   <h:column>
      <h:outputText value="#{hgrp.name}"/>
   </h:column>
</h:dataTable>

Leider sieht das ganze nicht gut aus. Daher wollte ich das ganze tabellarisch aufbauen.

Das Problem nun ist, dass ich es einfach nicht hinbekomme. In diesem Beispiel kann ein User Mitglied mehrerer UserGroups (List) sein. Und eine UserGroup kann mehreren HostGroups (auch eine List) zu geordnet sein. Und eine HostGroup kann mehrere Hosts haben (auch eine List).

Ich habe gedacht das es ungefähr so gehen müsste, aber irgendwie drehe ich mich im Kreis und nichts funktioniert.

Code:
	 	<
h:dataTable value="#{userControler.ugroups}" var="ugrp" border="1"
	 		styleClass="order-tabel" 
	 		headerClass="order-table-header" 
	 		rowClasses="order-table-odd-row,order-table-even-row"
>
   <h:column>
      <f:facet name="header">User Groups</f:facet>
      <h:outputText value="#{ugrp.name}"/>
   </h:column>
   <h:column>
      <f:facet name="header">Host Groups</f:facet>
      <h:outputText value="#{hgrp.name}"/>					
   </h:column>
   <h:column>
      <f:facet name="header">Hosts</f:facet>
      <h:outputText value="#{host.name}"/>					
   </h:column>
</h:dataTable>

Hat jemand einen Tipp für mich, wie ich das Problem richtiger angehen kann? Ich finde grade von selbst keine Lösung.

Gruß
 

sence

Bekanntes Mitglied
Dein Problem ist recht einfach zu erklären :)
Schau dir mal dein zuerst gepostetes Beispiel an, dann dein zweites.


Wenn du es jetzt noch nicht siehst, hier die Auflösung :)
Beispiel eins:
Java:
<h:dataTable value="#{userControler.ugroups}" var="ugrp">
.......
.......

<h:dataTable value="#{userControler.hgroups}" var="hgrp">
.....
....
Das Funktioniert, da jedes Element in deiner Liste als Variablen Name ugrp bzw. hgrp in der 2. Datatable referenziert wird.

Bei deinem 2. Beispiel, hast du nur folgendes stehen:
Java:
<h:dataTable value="#{userControler.ugroups}" var="ugrp"......
.....
hier, versucht du auch auf hgrp zuzugreifen, doch woher soll es herkommen?

Die Lösung:
wenn du auf alle Elemente zugriff haben möchtest, muss die Liste mit dem höchsten "Parent" Objekt als Liste referenziert werden.
Die Unterelemente müssen dann in dem jeweiligen "Parent" Objekt erreichbar sein.

Beispiel:
Host
->HostGroup
-> UserGroup

Wenn du jetzt die Liste mit List<Hosts> lst_host referenzierst kannst du wie folgt auf die Unterlemente zugreifen:

Java:
<h:dataTable value="#{userControler.hosts}" var="hosts" ....
<h:column>
      <f:facet name="header">User Groups</f:facet>
      <h:outputText value="#{hosts.hostgroup.ugrp.name}"/>
   </h:column>
   <h:column>
      <f:facet name="header">Host Groups</f:facet>
      <h:outputText value="#{hosts.hostgroup.name}"/>					
   </h:column>
   <h:column>
      <f:facet name="header">Hosts</f:facet>
      <h:outputText value="#{hosts.name}"/>					
   </h:column>
</h:dataTable>

zur Vollständigkeit halber:
es geht natürlich auch andersherum, vom niedrigsten Objekt zum höchsten, also:
ugrp.hgrp.hosts
oder wie ich es geschrieben habe (vom höchsten nach unten)
hosts.hgrp.ugrp

Grüße
 
Zuletzt bearbeitet:

AndiE

Top Contributor
Das habe ich nicht richtig verstanden

Ich habe in einem Bean

Java:
@ManagedBean(name="schulen")
...
Schule[] Schullist= new Schule[8];
...

und habe dann im Facelet

[XML]
...
<h:DataTable value="#{schulen.Schullist}" var="s">
...

<h:column>
#{s.Name}
</h:column>
...
[/XML]

Wenn ich Schule-Klasse-Schueler habe, dann würde ich ( nur skizzenhaft) das so anlegen:

Java:
class Schueler{
...
private String name;
...
}

class Klasse
{
   private Schueler[] s= new Schueler[20];
}
...

@managedBean(name="schule")
public class Schule{
private Klasse[] Klassenliste= new Klasse[20];

}

anlegen.

Wie geht das jetzt mit der Referenzierung? Oder geht das nur bei Listen. wie würde es da aussehen?
 

sence

Bekanntes Mitglied
jetzt kannst du, (bei deinem Aufbau)

auf die einzelnen Element wie folgt zugreifen:

Java:
<h:column>
#{s.Name} #{s.Klassenliste[0].s[0].name}
</h:column

auf die Schule-> dann auf das erste Objekt der Klassenliste [0] -> dann auf den ersten schüler [0] -> auf den Namen -> .name
zugreifen.

Mit Referenzieren wollte ich ausdrücken, das aus einem Objekt, die anderen Objekte erreichbar sein müssen.
bzw mit der Referenzierung bei value="" war gemeint, dass man nur eine Liste angeben kann, die iteriert werden soll.

Kleine Anmerkung, variablen klein schreiben, Klassen Namen groß.
 

azenth

Mitglied
Hallo sense,

danke dir erstmal für den Tipp. Aber ich habe iregndwie noch ein Problem.

Ich habe nun die dataTable entsprechend umgebaut.

Code:
<h:dataTable value="#{userControler.groups}" var="grps" border="1"
	 		styleClass="order-tabel" 
	 		headerClass="order-table-header" 
	 		rowClasses="order-table-odd-row,order-table-even-row"
>
<h:column>
   <f:facet name="header">User Groups</f:facet>
   <h:outputText value="#{grps.name}"/>
</h:column>
<h:column>
   <f:facet name="header">Host Groups</f:facet>
   <h:outputText value="#{grps.hostgroup.name}"/>		 			
</h:column>
<h:column>
   <f:facet name="header">Hosts</f:facet>
   <h:outputText value="#{grps.hostgroup.host.name}"/>					
</h:column>
</h:dataTable>

Jedoch erhalte ich in meiner xhtml-Datei folgende Fehlermeldung: name cannot be resolved as a member of hostgroup

Kann es sein das ich beim referenzieren etwas falsch gemacht habe???

Die entsprechenden Java-Klassen schauen wie folgt aus:

UserGroup-Klasse

Code:
public class UserGroup implements Serializable {

	private static final long serialVersionUID = 1L;
	private transient Logger logger = Logger.getLogger(this.getClass().getName());

	private String name;
	private int db_id;
	
	List<HostGroup> groups = new ArrayList<HostGroup>();

	private DataSource datasource;

	public UserGroup() {
		super();
	}
	
	public UserGroup(int id, String name) {
		super();
		initHostGroups(this.name);
		this.name = name;
		this.db_id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getId() {
		return db_id;
	}

	public void setId(int id) {
		this.db_id = id;
	}
	
	public List<HostGroup> getHostgroup() {
		return groups;
	}

	public void setHostgroup(int id) {
		this.groups = groups;
	}
	
	public void initHostGroups(String ug) {
		
		Connection conn = null;
		Statement stmt = null;
		
		List<HostGroup> hostgroups = null;
		
		try {
			conn = datasource.getConnection();
			stmt = conn.createStatement();
		
		String groupsql = 	"SELECT H.hostgroup_name, H.hostgroup_id " +
   							"FROM vw_hostgroup H, vw_usergroup U, hostgroup_usergroup HG " +
							"WHERE U.usergroup_name = '" + ug + "' " +
							"AND U.usergroup_id = HG.usergroup_id " +
							"AND HG.hostgroup_id = H.hostgroup_id";
   				   			
		ResultSet rs_group = stmt.executeQuery(groupsql);
		while (rs_group.next()) {
			String name = rs_group.getString("hostgroup_name");
			int id = rs_group.getInt("hostgroup_id");
			HostGroup g = new HostGroup(id, name);

			logger.fine("Add group(s) to usergroup " + g);
			
			groups.add(g);
  		}
		} catch (SQLException e) {
			logger.log(Level.SEVERE, "SQL problem while getting data", e);
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (Exception e) {
				/* ignore */
			}
		}
	}

und

Code:
public class HostGroup implements Serializable{
	
	private static final long serialVersionUID = 1L;
	private transient Logger logger = Logger.getLogger(this.getClass().getName());

	private String name;
	private int db_id;

	private DataSource datasource;

	public HostGroup() {
		super();
	}

	public HostGroup(int id, String name) {
		super();
		this.name = name;
		this.db_id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getId() {
		return db_id;
	}

	public void setId(int id) {
		this.db_id = id;
	}

Ich hätte jetzt eigentlich erwartet, dass die getter und setter - - Methoden der Klasse Hostgroup nun verfügbar sind innerhalb der UserGroup und somit auch die Fehlermeldung nicht mehr erscheinen dürfte?

Habe ich etwas übersehen? Wie gesagt, dies ist eventuell ein schwerer Einstieg für einen Anfänger aber mit ein bisschen Hilfe beiße ich mich da durch.

Gruß
 

sence

Bekanntes Mitglied
du hast in UserGroup die Liste:
Java:
List<HostGroup> groups = new ArrayList<HostGroup>();

aber der Getter heißt:
Java:
public List<HostGroup> getHostgroup() {
		return groups;
	}

und dein Setter ist falsch:

Java:
	public void setHostgroup(int id) { // Wieso ein int, als Setter für eine Liste, es müsste eine Liste sein, die der Setter übergeben bekommt
		this.groups = groups;
	}

du müsstest dann diekt den Getter #{grps.getHostgroup()} verwenden.
nenne die Getter entsprechend der Variablen:
variable: groups
getter: getGroups() { ... };
setter: setGroups(...) { ...};

jetzt kannst du ganz normal wie folgt darauf zugreifen: #{grps.groups.weiteresObjekt.name}

Aber beachte: bei der Implementierung, greifst du nur auf die Liste zu, aber nicht auf einen der Listeneinträge.
das würde dann so aussehen: #{grps.groups[0].name}
 
Zuletzt bearbeitet:

JanHH

Top Contributor
Irgendwie scheint mir das Problem eher grundsätzlich.. es liegt ein Datenmodell vor, welches aus mehreren geschachtelten Listen besteht (wobei ich es nicht ganz verstehe, aber egal). Die Frage ist ganz allgemein, wie ist das Modell aufgebaut, in welchen Beziehungen zueinander stehen die Daten, und wie kann man das vernünftig visualisieren. Ich bezweifle stark, sich das überhaupt vernünftig in einer einzigen dataTable darstellen lässt. Eher mit mehreren geschachtelten, oder einem Tree, oder einer Kombinattion aus Tree und Tabelle.. Überleg Dir doch erstmal was Du überhaupt genau willst bzw. was dein Datenmodell da für Notwendigkeiten mitbringt.
 

sence

Bekanntes Mitglied
Er will auf mehrere Objekte innerhalb der Objekte welche in der Liste sind zugreifen.
Soweit ist es okay, die Ausgabe der Unterlisten innerhalb einer Datatable ist nur mit weiteren Iterationen, wie z.B.

ui:repeat
möglich.

Wie die Tabelle schlussendlich aussehen soll, dass sollte man schon wissen, da gebe ich dir recht jan :)
Wollte ihm aber erstmal zeigen, wie er von was auf was kommt, damit er dann selbst sich in zukunft andere Gestricke bauen kann ,)

greetz, so kunden meeting bye bye
JSFAtWork, JSF 2.0 und Apache MyFaces
 
Zuletzt bearbeitet:

JanHH

Top Contributor
*kopfschüttel

Java:
<h:dataTable value="#{liste1}" var="v1">
   <h:column>
      <h:dataTable value="#{v1.liste2}" var="v2">
         <h:column>
            ...
         </h:column>
      </h:dataTable>
   </h:column>
</h:dataTable>
 

sence

Bekanntes Mitglied
wieso schüttelst du mit dem kopf ?

ui:repeat ist eine Möglichkeit, verschachtelte Datatable's sind ebenfalls eine.
Bei Verwendung von ui:repeat, wird weniger HTML Quellcode generiert, da keine zusätzliche Table erstellt wird.
 
Zuletzt bearbeitet:

JanHH

Top Contributor
Hm dann hab ich Dich vielleicht falsch verstanden. Nämlich so, das keine geschachtelten dataTables gehen sondern NUR ui:repeat. Dann nich schüttel sondern nick.
 

azenth

Mitglied
Hallo nochmal,

also ich habe es geschafft, dass die Spalten gefüllt werden. Zwar stehen, da momentan noch falsche Werte drin, aber das liegt nun mehr an meinen Java-Klassen, die ich überarbeiten muss.

Wie gesagt, da ich mich erst seit einer Woche mit JSF 2.0 versuche, fällt es mir noch echt schwer die Trennung zwischen Frontend, Controllern und Backend zu machen. Ich hoffe, dass gibt sich mit der Zeit.

Gruß
 

azenth

Mitglied
Hallo,

ich habe leider noch eine Frage an euch. Nachdem ich meine Java-Klassen mit Kommentaren versehen habe und für die dataTable ein CSS-File erstellt habe, fügte ich noch die Host-Klasse hinzu und stellte überrascht fest, dass mir keine Hosts angezeigt wurden.

Daraufhin habe ich das Logging hochgedreht und mir ich bin mir sicher, dass der Fehler bei der dritten dataTable sein muss. Weil die Java-Klassen alle die richtigen Werte in den Listen zurückliefern. Eigentlich habe ich alles gemacht wie sence es beschrieben hat, aber eventuell ist da doch noch irgendwo ein Fehler.

Code:
<h:dataTable value="#{userControler.usergroups}" var="groups"
	 		styleClass="order-table" headerClass="order-table-header" rowClasses="order-table-odd-row, order-table-even-row"
	 		columnClasses="order-table-cell-left, order-table-cell-mid, order-table-cell-right"
	 	>
	 		<h:column>
	 			<f:facet name="header" class="header">User Groups</f:facet>
	 			<h:outputText value="#{groups.name}"/>
	 		</h:column>
	 		<h:column>
	 			<f:facet name="header">Host Groups</f:facet>
				<h:dataTable value="#{groups.hostgroups}" var="hgroups" styleClass="order-table2" rowClasses="order-table2-odd-row, order-table2-even-row">
					<h:column>
						<h:outputText value="#{hgroups.name}"/>	
					</h:column>
				</h:dataTable>
			</h:column>
			<h:column>
	 			<f:facet name="header">Hosts</f:facet>
				<h:dataTable value="#{hgroups.host}" var="host" styleClass="order-table2" rowClasses="order-table2-odd-row, order-table2-even-row">
					<h:column>
						<h:outputText value="#{host.name}"/>	
					</h:column>
				</h:dataTable>
			</h:column>
		 </h:dataTable>

Wenn ich statt value="#{host.name}" value="#{userControler.usergroups.hostgroups.host.name}" schreibe, dann bekomme ich folgenden Fehler zurück: hostgroup cannot resolved as a member of usergroup.

Ich stehe grade echt vor einem Rätsel.
 

azenth

Mitglied
Hallo,

ich bin es nochmal. Ich kenne nun den Grund warum ich in der Spalte Hosts keine Daten bekomme.

Code:
<h:dataTable value="#{userControler.usergroups}" var="usergroups"
	 		styleClass="order-table" headerClass="order-table-header" rowClasses="order-table-odd-row, order-table-even-row"
	 		columnClasses="order-table-cell-left, order-table-cell-mid, order-table-cell-right"
	 	>
	 		<h:column>
	 			<f:facet name="header" class="header">User Groups</f:facet>
	 			<h:outputText value="#{usergroups.name}"/>
	 		</h:column>
	 		<h:column>
	 			<f:facet name="header">Host Groups</f:facet>
				[COLOR="DarkRed"]<h:dataTable value="#{usergroups.hostgroups}" var="hostgroups"[/COLOR] styleClass="order-table2" rowClasses="order-table2-odd-row, order-table2-even-row">
					<h:column>
						<h:outputText value="#{hostgroups.name}"/>	
					</h:column>
				[COLOR="DarkRed"]</h:dataTable>[/COLOR]
			</h:column>
			<h:column>
	 			<f:facet name="header">Hosts</f:facet>
				<h:dataTable value="#{hostgroups.hosts}" var="host" styleClass="order-table2" rowClasses="order-table2-odd-row, order-table2-even-row">
					<h:column>
						<h:outputText value="#{host.name}"/>	
					</h:column>
				</h:dataTable>
			</h:column>
		 </h:dataTable>

Es liegt daran, dass ich bei die 2te dataTable schließe (in rot markiert) bevor ich die 3te öffne und dadurch die Variable hostgroups nicht mehr bekannt ist. Jetzt habe ich versucht das irgendwie ineinander zu verschachteln aber jedesmal geht dadurch meine Tabellenstruktur kaputt. Kennt da jemand eine gängige Lösung für mehrfachverschachtelte dataTables oder kann man die Variable irgendwie global machen?

Gruß
 

sence

Bekanntes Mitglied
Bin mir gerade nicht sicher, aber so in der Art könnte es funktionieren.

Hinweis:
Es ist freihändig geschrieben, keine garantie dass alle Tags richtig geschrieben sind.
Relevant ist die 3. Datatable

Java:
<h:dataTable value="#{userControler.usergroups}" var="usergroups"
	 		styleClass="order-table" headerClass="order-table-header" rowClasses="order-table-odd-row, order-table-even-row"
	 		columnClasses="order-table-cell-left, order-table-cell-mid, order-table-cell-right"
	 	>
	 		<h:column>
	 			<f:facet name="header" class="header">User Groups</f:facet>
	 			<h:outputText value="#{usergroups.name}"/>
	 		</h:column>
	 		<h:column>
	 			<f:facet name="header">Host Groups</f:facet>
				[COLOR="DarkRed"]<h:dataTable value="#{usergroups.hostgroups}" var="hostgroups"[/COLOR] styleClass="order-table2" rowClasses="order-table2-odd-row, order-table2-even-row">
					<h:column>
						<h:outputText value="#{hostgroups.name}"/>	
					</h:column>
				[COLOR="DarkRed"]</h:dataTable>[/COLOR]
			</h:column>
			<h:column>
	 			<f:facet name="header">Hosts</f:facet>
				<h:dataTable value="#{usergroups.hostgroups}" var="hostgroups" styleClass="order-table2" rowClasses="order-table2-odd-row, order-table2-even-row">
					<h:column>
						<ui:repeat value="#{usergroups.hostgroups.hosts}"  var="host">
                                                  <h:outputText value="#{host.name"} />
                                                </ui:repeat>
					</h:column>
				</h:dataTable>
			</h:column>
		 </h:dataTable>
 
Zuletzt bearbeitet:

Neue Themen


Oben