Zum Hauptinhalt springen

Rendering

In ChatGPT öffnen
24.00
Java API

Ein Renderer steuert, wie jede Zelle in einer Spalte angezeigt wird. Anstatt einen Rohwert anzuzeigen, transformiert ein Renderer die Daten jeder Zelle in formatierte Texte, Icons, Abzeichen, Links, Aktionsknöpfe oder jede andere Visualisierung, die die Daten schneller lesbar und einfacher umsetzbar macht.

Das Rendering erfolgt vollständig im Browser. Der Server sendet Rohdaten und der Client übernimmt die Präsentation, wodurch die 'Tabelle' unabhängig von der Zeilenanzahl schnell bleibt.

Weisen Sie einem Renderer eine Spalte mit setRenderer() zu. Der Renderer wird einheitlich auf jede Zelle in dieser Spalte angewendet:

TextRenderer<MusicRecord> renderer = new TextRenderer<>();
renderer.setTheme(Theme.PRIMARY);

table.addColumn("title", MusicRecord::getTitle).setRenderer(renderer);
Renderer vs. Wertanbieter

Wenn Sie nur einen Zellwert transformieren oder formatieren müssen, ohne eine DOM-Struktur zu erzeugen, verwenden Sie stattdessen einen Wertanbieter. Renderer erzeugen zusätzliche DOM-Elemente für jede gerenderte Zeile, was während des Renderns Kosten verursacht. Reservieren Sie Renderer für visuelle Ausgaben wie Icons, Abzeichen, Schaltflächen oder andere HTML-basierte Präsentationen.

webforJ verfügt über integrierte Renderer für die häufigsten Anwendungsfälle. Für alles, was spezifisch für Ihre App ist, erweitern Sie Renderer und implementieren Sie build(), um einen lodash-Vorlagenstring zurückzugeben, der im Browser für jede Zelle ausgeführt wird.

Häufig verwendete Renderer

Die folgenden Beispiele erläutern vier häufig verwendete Renderer und zeigen das setRenderer()-Muster in der Praxis.

TextRenderer

Zeigt den Zellinhalt als einfachen oder formatierten Text an. Wenden Sie eine Themenfarbe oder Textdekoration auf eine Spalte an, ohne deren Struktur zu ändern, wie z.B. Hervorhebung eines Prioritätsfeldes in Rot oder Fettdruck eines Schlüsselbezeichners.

TextRenderer<MusicRecord> renderer = new TextRenderer<>();
renderer.setTheme(Theme.PRIMARY);
renderer.setDecorations(EnumSet.of(TextDecoration.BOLD));

table.addColumn("title", MusicRecord::getTitle).setRenderer(renderer);

BadgeRenderer

Umhüllt den Zellwert in einem Abzeichen-Element. Unterstützt Themen, Ausdehnungen, Farben (automatische unterschiedliche Farben pro einzigartigem Wert) und ein optionales führendes Icon. Verwenden Sie es für kategoriale Werte wie Tags, Typen oder Bezeichnungen, bei denen unterschiedliche visuelle Chips den Benutzern helfen, Zeilen schnell zu scannen und zu vergleichen.

BadgeRenderer<MusicRecord> renderer = new BadgeRenderer<>();
renderer.setTheme(BadgeTheme.PRIMARY);

table.addColumn("musicType", MusicRecord::getMusicType).setRenderer(renderer);

BooleanRenderer

Ersetzt true, false und null-Werte durch Icons. Verwenden Sie es für jede true/false-Spalte, bei der ein Icon den Wert schneller kommuniziert als Text, wie z.B. bei Feature-Flags, aktiven/inaktiven Zuständen oder Opt-in-Feldern.

// Standard-Icons
BooleanRenderer<Task> renderer = new BooleanRenderer<>();
table.addColumn("completed", Task::isCompleted).setRenderer(renderer);

// Benutzerdefinierte Icons
BooleanRenderer<Task> custom = new BooleanRenderer<>(
TablerIcon.create("thumb-up").setTheme(Theme.SUCCESS),
TablerIcon.create("thumb-down").setTheme(Theme.DANGER)
);
table.addColumn("completed", Task::isCompleted).setRenderer(custom);

CurrencyRenderer

Formatiert einen numerischen Wert als Währungsbetrag unter Verwendung der Regeln der angegebenen Locale. Verwenden Sie es für jede monetäre Spalte, bei der die lokalisierte Formatierung (Symbol, Trennzeichen, Dezimalstellen) wichtig ist.

// US-Dollar
table.addColumn("cost", MusicRecord::getCost)
.setRenderer(new CurrencyRenderer<>(Locale.US));

// Euro mit deutscher Locale
table.addColumn("retail", MusicRecord::getRetail)
.setRenderer(new CurrencyRenderer<>(Locale.GERMANY));

Bedingtes Rendering

ConditionalRenderer wählt einen anderen Renderer pro Zelle basierend auf dem Wert der Zelle aus. Die Bedingungen werden in der Reihenfolge ausgewertet; der erste Treffer gewinnt. Ein Auffangbecken kann mit otherwise() festgelegt werden.

Das folgende Beispiel zeigt bedingtes Rendering, das auf eine Rechnungsstatusspalte angewendet wird, und wechselt zwischen BadgeRenderer-Varianten abhängig vom Wert:

Code anzeigen

Es funktioniert auch gut für numerische Schwellenwerte. Dieses Server-Dashboard verwendet ConditionalRenderer, um die Themen des ProgressBarRenderer basierend auf CPU- und Speicherverbrauchsniveaus zu wechseln:

Code anzeigen

Bedingungen API

Bedingungen werden mit statischen Fabrikmethoden erstellt und können mit and(), or() und negate() kombiniert werden.

// Wertgleichheit
Condition.equalTo("active")
Condition.equalToIgnoreCase("active")
Condition.in("active", "pending", "new")

// Numerische Vergleiche
Condition.greaterThan(100)
Condition.lessThanOrEqual(0)
Condition.between(10, 50)

// Boolean / Leere
Condition.isTrue()
Condition.isFalse()
Condition.isEmpty()

// Zeichenfolgenabgleich
Condition.contains("error")
Condition.containsIgnoreCase("warn")

// Zusammensetzung
Condition.greaterThan(0).and(Condition.lessThan(100))
Condition.isEmpty().or(Condition.equalTo("N/A"))
Condition.isTrue().negate()

// Überprüfung über Spalten hinweg
Condition.column("status").equalTo("active")

// Raw JavaScript-Ausdruck
Condition.expression("cell.value % 2 === 0")

Komposit-Rendering

CompositeRenderer kombiniert mehrere Renderer nebeneinander in einer einzigen Zelle unter Verwendung eines Flex-Layouts. Verwenden Sie es, um ein Icon mit Text zu kombinieren, einen Avatar neben einem Namen anzuzeigen oder ein Abzeichen neben einem Statusindikator zu stapeln.

Das Mitarbeitereinverzeichnis unten verwendet einen CompositeRenderer in der Mitarbeiter-Spalte, um einen automatisch generierten Avatar neben dem Namen jedes Mitarbeiters anzuzeigen:

Code anzeigen

Benutzerdefinierte Renderer

Wenn kein integrierter Renderer zu Ihrem Anwendungsfall passt, erweitern Sie Renderer und implementieren Sie build(). Die Methode gibt einen lodash-Vorlagenstring zurück, der im Browser für jede Zelle in der Spalte ausgeführt wird und eine Mischung aus HTML und JavaScript ausdrückt.

Erstellen eines benutzerdefinierten Renderers

Schritt 1: Erweitern Sie Renderer mit Ihrem Zeilendatentyp.

public class RatingRenderer extends Renderer<MusicRecord> {

Schritt 2: Überschreiben Sie build() und geben Sie einen lodash-Vorlagenstring zurück.

  @Override
public String build() {
return /* html */"""
<%
const rating = Number(cell.value);
const stars = Math.round(Math.min(Math.max(rating, 0), 5));
const full = '★'.repeat(stars);
const empty = '☆'.repeat(5 - stars);
%>
<span><%= full %><%= empty %></span>
<span style="color: var(--dwc-color-body-text)">(<%= rating.toFixed(1) %>)</span>
""";
}
}

Schritt 3: Weisen Sie den Renderer einer Spalte zu.

table.addColumn("rating", MusicRecord::getRating)
.setRenderer(new RatingRenderer());
Tipp

Für weitere Informationen zur Verwendung von Lodash-Syntax zum Zugriff auf Zellinformationen und zur Erstellung informativer Renderer siehe diesen Referenzabschnitt.

Zugriff auf mehrere Spalten

Verwenden Sie cell.row.getValue("columnId"), um Geschwisterspalten innerhalb der Vorlage auszulesen. Dies ist nützlich, um Felder zu kombinieren, Deltas zu berechnen oder verwandte Daten abzugleichen.

public class ArtistAvatarRenderer extends Renderer<MusicRecord> {
@Override
public String build() {
return /* html */"""
<%
const name = cell.row.getValue("artist");
const initials = name
? name.split(' ').map(w => w.charAt(0)).join('').substring(0, 2).toUpperCase()
: '?';
%>
<div style="display: flex; align-items: center; gap: 8px;">
<div style="width: 28px; height: 28px; border-radius: 50%;
background: var(--dwc-color-primary); color: white;
display: flex; align-items: center; justify-content: center;
font-size: 11px; font-weight: 600;">
<%= initials %>
</div>
<span><%= name %></span>
</div>
""";
}
}

Klickereignisse

IconButtonRenderer und ButtonRenderer bieten addClickListener() standardmäßig an. Das Klickereignis bietet über e.getItem() Zugriff auf das Datenobjekt der Zeile.

IconButtonRenderer<MusicRecord> deleteBtn = new IconButtonRenderer<>(
TablerIcon.create("trash").setTheme(Theme.DANGER)
);
deleteBtn.addClickListener(e -> {
MusicRecord record = e.getItem();
repository.delete(record);
table.refresh();
});

table.addColumn("delete", r -> "").setRenderer(deleteBtn);

Leistung: Faules Rendering 25.12

Für Spalten, die visuell aufwändige Renderer wie Abzeichen, Fortschrittsbalken, Avatare oder Webkomponenten verwenden, aktivieren Sie faules Rendering, um die Scroll-Leistung zu verbessern.

table.addColumn("status", Order::getStatus)
.setRenderer(new BadgeRenderer<>())
.setLazyRender(true);

Wenn setLazyRender(true) für eine Spalte gesetzt ist, zeigen Zellen einen leichten animierten Platzhalter an, während der Benutzer scrollt. Der eigentliche Zellinhalt wird gerendert, sobald das Scrollen stoppt. Dies ist eine spaltenweite Einstellung, sodass Sie sie selektiv nur für die Spalten aktivieren können, die davon profitieren.

Code anzeigen

Wann faules Rendering aktivieren

Zellen-Renderer erstellen mehr Entitäten innerhalb des DOMs, was mehr CPU-Arbeit während des Renderns bedeutet, unabhängig davon, welcher Renderer es erzeugt.

Faules Rendering kann helfen, die Leistungseinbußen zu reduzieren, wenn ein Renderer wirklich benötigt wird. Wenn Sie nur den Wert ändern oder formatieren müssen und kein komplexes DOM erstellen, verwenden Sie stattdessen einen Wertanbieter, um den Wert zu transformieren.

Referenz der integrierten Renderer

webforJ wird mit einem umfassenden Satz von Renderern für die häufigsten Anwendungsfälle geliefert. Weisen Sie einen beliebigen davon einer Spalte mit column.setRenderer(renderer) zu.

Code anzeigen

Texte und Bezeichnungen

25.12

Zeigt den Zellinhalt als einfachen oder formatierten Text an. Unterstützt Themenfarben und Textdekorationen wie fett, kursiv und unterstrichen.

TextRenderer renderer = new TextRenderer<>();
renderer.setTheme(Theme.PRIMARY);
renderer.setDecorations(EnumSet.of(TextDecoration.BOLD));

table.addColumn("title", MusicRecord::getTitle).setRenderer(renderer);
25.12

Umhüllt den Zellwert in einem Abzeichen-Element. Unterstützt Themen, Ausdehnungen, Farbseeding (automatisch unterschiedliche Farben pro einzigartigem Wert) und ein optionales führendes Icon.

BadgeRenderer renderer = new BadgeRenderer<>();
renderer.setTheme(BadgeTheme.PRIMARY);

table.addColumn("musicType", MusicRecord::getMusicType).setRenderer(renderer);
25.12

Gerenderte eine konfigurierbare Rückfallzeichenfolge, wenn der Zellwert null oder leer ist; andernfalls wird der Wert unverändert gerendert.

table.addColumn("notes", MusicRecord::getNotes)
.setRenderer(new NullRenderer<>("N/A"));

Status und Indikatoren

25.12

Ersetzt true, false und null-Werte durch Icons. Standardmäßig ein Häkchen, ein Kreuz und ein Strich.

// Standard-Icons
BooleanRenderer renderer = new BooleanRenderer<>();
table.addColumn("completed", Task::isCompleted).setRenderer(renderer);

// Benutzerdefinierte Icons
BooleanRenderer custom = new BooleanRenderer<>(
TablerIcon.create("thumb-up").setTheme(Theme.SUCCESS),
TablerIcon.create("thumb-down").setTheme(Theme.DANGER)
);
25.12

Zeigt einen kleinen farbigen Punkt links vom Zellwert an. Ordnen Sie einzelne Werte Themen, CSS-Farbcodes oder java.awt.Color-Instanzen zu.

StatusDotRenderer renderer = new StatusDotRenderer<>();
renderer.addMapping("Active", Theme.SUCCESS);
renderer.addMapping("Pending", Theme.WARNING);
renderer.addMapping("Cancelled", Theme.DANGER);

table.addColumn("status", Order::getStatus).setRenderer(renderer);

Zahlen, Währungen und Daten

25.12

Formatiert einen numerischen Wert als Währungsbetrag unter Verwendung der Regeln der angegebenen Locale.

// US-Dollar
table.addColumn("cost", MusicRecord::getCost)
.setRenderer(new CurrencyRenderer<>(Locale.US));

// Euro mit deutscher Locale
table.addColumn("retail", MusicRecord::getRetail)
.setRenderer(new CurrencyRenderer<>(Locale.GERMANY));
25.12

Zeigt einen numerischen Wert als Prozentsatz an. Setzen Sie das zweite Konstruktorargument auf false, um das Rendern eines dünnen Fortschrittbalkens unter dem Text zu verhindern.

PercentageRenderer renderer = new PercentageRenderer<>(Theme.PRIMARY, true);
table.addColumn("completion", Task::getCompletion).setRenderer(renderer);
25.12

Gerendert einen vollflächigen Fortschrittsbalken mit konfigurierbaren minimalen und maximalen Werten, unbestimmtem Modus und gestreiftem oder animiertem Display. Verwenden Sie setText() mit einem lodash-Ausdruck, um benutzerdefinierten Text auf dem Balken zu überlagern.

ProgressBarRenderer renderer = new ProgressBarRenderer<>();
renderer.setMax(100);
renderer.setTheme(Theme.SUCCESS);
renderer.setTextVisible(true);
renderer.setText("<%= cell.value %>/100");

table.addColumn("progress", Task::getProgress).setRenderer(renderer);
25.12

Wendet eine Zeichenmaskierung auf einen Zeichenfolgewert an. # entspricht jeder Ziffer; literale Zeichen werden beibehalten. Siehe Textmaskenregeln für alle unterstützten Maskenzeichen.

table.addColumn("ssn", Employee::getSsn)
.setRenderer(new MaskedTextRenderer<>("###-##-####"));
25.12

Formatiert einen numerischen Wert mithilfe eines Musters mit lokalisierten Trennzeichen. 0 zwingt eine Ziffer; # ist optional. Siehe Zahlenmaskenregeln für alle unterstützten Maskenzeichen.

table.addColumn("price", Product::getPrice)
.setRenderer(new MaskedNumberRenderer<>("###,##0.00", Locale.US));
25.12

Formatiert einen Datum- oder Zeitwert mithilfe von Mustertokens: %Mz (Monat), %Dz (Tag), %Yz (Jahr) und anderen. Siehe Datumsmaskenregeln für alle verfügbaren Tokens.

table.addColumn("released", MusicRecord::getReleaseDate)
.setRenderer(new MaskedDateTimeRenderer<>("%Mz/%Dz/%Yz"));
25.12

Umhüllt den Zellwert in einem mailto:-Link. Ein primär thematisches Mail-Icon dient standardmäßig als visuelles Element.

// Standardmail-Icon
table.addColumn("email", Contact::getEmail)
.setRenderer(new EmailRenderer<>());

// Benutzerdefiniertes Icon
table.addColumn("email", Contact::getEmail)
.setRenderer(new EmailRenderer<>(TablerIcon.create("at")));
25.12

Umhüllt den Zellwert in einem tel:-Link. Auf mobilen Geräten wird beim Tippen die Wählfunktion geöffnet. Ein primär thematisches Telefon-Icon wird standardmäßig angezeigt.

// Standardtelefon-Icon
table.addColumn("phone", Contact::getPhone)
.setRenderer(new PhoneRenderer<>());

// Benutzerdefiniertes Icon
table.addColumn("phone", Contact::getPhone)
.setRenderer(new PhoneRenderer<>(TablerIcon.create("device-mobile")));
25.12

Gerendert ein klickbares Anker-Element. Das href unterstützt lodash-Vorlagen-Ausdrücke, sodass Sie URLs dynamisch aus dem Zellwert erstellen können.

AnchorRenderer renderer = new AnchorRenderer<>();
renderer.setHref("https://www.google.com/search?q=<%= cell.value %>");
renderer.setTarget("_blank");

table.addColumn("title", MusicRecord::getTitle).setRenderer(renderer);
25.12

Zeigt ein Bild an. Das src-Attribut unterstützt lodash-Vorlagen-Ausdrücke, sodass jede Zeile ein unterschiedliches Bild anzeigen kann.

ImageRenderer renderer = new ImageRenderer<>();
renderer.setSrc("https://placehold.co/40x40?text=<%= cell.value %>");
renderer.setAlt("Cover");

table.addColumn("cover", MusicRecord::getArtist).setRenderer(renderer);

Personen und Avatare

25.12

Gerendert eine Avatar-Komponente. Die Initialen werden automatisch aus dem Zellwert abgeleitet. Unterstützt Themen und ein Fallback-Icon.

AvatarRenderer renderer = new AvatarRenderer<>();
renderer.setTheme(AvatarTheme.PRIMARY);
renderer.setIcon(TablerIcon.create("user"));

table.addColumn("artist", MusicRecord::getArtist).setRenderer(renderer);

Icons und Aktionen

24.00

Gerendert ein einzelnes Icon. Fügen Sie einen Klicklistener für interaktive Funktionen hinzu.

IconRenderer renderer = new IconRenderer<>(TablerIcon.create("music"));
table.addColumn("type", MusicRecord::getMusicType).setRenderer(renderer);
25.12

Gerendert ein klickbarer Icon-Button. Das Klickereignis gibt das Zeilenobjekt über e.getItem() frei, was es ideal für zeilenbezogene Aktionen macht.

IconButtonRenderer renderer = new IconButtonRenderer<>(TablerIcon.create("edit"));
renderer.addClickListener(e -> openEditor(e.getItem()));

table.addColumn("actions", r -> "").setRenderer(renderer);
24.00

Gerendert eine vollständige Button-Komponente innerhalb der Zelle.

ButtonRenderer renderer = new ButtonRenderer<>("Edit");
renderer.setTheme(ButtonTheme.PRIMARY);
renderer.addClickListener(e -> openEditor(e.getItem()));

table.addColumn("edit", r -> "Edit").setRenderer(renderer);
24.00

Gerendert ein beliebiges HTML-Element mit einem lodash-Vorlageninhalt. Dies ist der Fluchtweg für Situationen, in denen kein integrierter Renderer passt.

ElementRenderer renderer = new ElementRenderer<>("span", "<%= cell.value %>");
table.addColumn("custom", MusicRecord::getTitle).setRenderer(renderer);

Vorlagenreferenz

Renderer bieten einen leistungsstarken Mechanismus zur Anpassung der Art und Weise, wie Daten in einer Tabelle angezeigt werden. Die Hauptklasse Renderer ist dafür ausgelegt, erweitert zu werden, um benutzerdefinierte Renderer basierend auf lodash-Vorlagen zu erstellen, die die dynamische und interaktive Inhaltserstellung ermöglichen.

Lodash-Vorlagen ermöglichen das Einfügen von HTML direkt in Tabellenzellen, wodurch sie äußerst effektiv zur Darstellung komplexer Zellendaten in einer Tabelle werden. Dieser Ansatz erlaubt die dynamische Generierung von HTML basierend auf Zellendaten und erleichtert einen reichen und interaktiven Tabellenzellinhalt.

Lodash-Syntax

Der folgende Abschnitt beschreibt die Grundlagen der Lodash-Syntax. Während dies keine vollständige oder umfassende Übersicht ist, kann es hilfreich sein, um mit Lodash innerhalb der Tabelle-Komponente zu beginnen.

Syntaxüberblick für lodash-Vorlagen:

  • <%= ... %> - Interpoliert Werte, indem das Ergebnis des JavaScript-Codes in die Vorlage eingefügt wird.
  • <% ... %> - Führt JavaScript-Code aus und erlaubt Schleifen, Bedingungsaussprüche und mehr.
  • <%- ... %> - Entkommt HTML-Inhalten, um sicherzustellen, dass interpolierte Daten vor HTML-Injection-Angriffen sicher sind.

Beispiele mit Zellendaten:

1. Einfache Wertinterpolation: zeigt direkt den Wert der Zelle an.

<%= cell.value %>

2. Bedingte Darstellung: verwendet JavaScript-Logik, um Inhalte bedingt darzustellen.

<% if (cell.value > 100) { %> 'Hoch' <% } else { %> 'Normal' <% } %>

3. Kombination von Datenfeldern: rendert Inhalte unter Verwendung mehrerer Datenfelder aus der Zelle.

<%= cell.row.getValue('firstName') + ' ' + cell.row.getValue('lastName') %>

4. Entkommen von HTML-Inhalten: sicherstellen, dass benutzergenerierte Inhalte sicher gerendert werden.

Der Renderer hat Zugriff auf detaillierte Zell-, Zeilen- und Spalteneigenschaften auf der Clientseite:

Eigenschaften der Tabelle-Zelle:

EigenschaftTypBeschreibung
columnTableColumnDas zugehörige Spaltenobjekt.
firstbooleanGibt an, ob die Zelle die erste in der Zeile ist.
idStringDie Zell-ID.
indexintDer Index der Zelle innerhalb ihrer Zeile.
lastbooleanGibt an, ob die Zelle die letzte in der Zeile ist.
rowTableRowDas zugehörige Zeilenobjekt für die Zelle.
valueObjectDer Rohwert der Zelle, direkt aus der Datenquelle.

Eigenschaften der Tabelle-Zeile:

EigenschaftTypBeschreibung
cellsTableCell[]Die Zellen innerhalb der Zeile.
dataObjectDie vom App für die Zeile bereitgestellten Daten.
evenbooleanGibt an, ob die Zeile gerade nummeriert ist (zum Zwecke des Stylings).
firstbooleanGibt an, ob die Zeile die erste in der Tabelle ist.
idStringEindeutige ID für die Zeile.
indexintDer Zeilenindex.
lastbooleanGibt an, ob die Zeile die letzte in der Tabelle ist.
oddbooleanGibt an, ob die Zeile ungerade nummeriert ist (zum Zwecke des Stylings).

Eigenschaften der Tabelle-Spalte:

EigenschaftTypBeschreibung
alignColumnAlignmentDie Ausrichtung der Spalte (links, zentriert, rechts).
idStringDas Feld des Zeilenobjekts, um die Zellendaten abzurufen.
labelStringDer Name, der in der Spaltenüberschrift gerendert wird.
pinnedColumnPinDirectionDie Pinnrichtung der Spalte (links, rechts, automatisch).
sortablebooleanWenn wahr, kann die Spalte sortiert werden.
sortSortDirectionDie Sortierreihenfolge der Spalte.
typeColumnTypeDer Typ der Spalte (Text, Zahl, Boolean usw.).
minWidthnumberDie Mindestbreite der Spalte in Pixel.