lange variable Parameterliste im String-Format
-
In einer Methode rufe ich mehrmals die Methode fit_textline auf, die drei konventionelle Parameter erfordert (String, double, double) und eine variable Parameterliste im String-Format hat (s.u., umfasst in diesem Beispiel die Optionen von boxsize bis position):
p.fit_textline(text, 0.0, 0.0, "boxsize = {" + boxWidth + " " + boxHeight + "} " + "embedding = true " + "encoding = unicode " + "fillcolor = {cmyk " + textColor.cyan + " " + textColor.magenta + " " + textColor.yellow + " " + textColor.key + "} " + "fitmethod = meet " + "fontname = input/fonts/" + fontName + " " + "fontsize = " + banderoleWidth + " " + "margin = " + banderoleWidth / 5 + " " + "position = {center center}");
Da diese extrem lange variable Parameterliste immer in der genau gleichen Form vorkommt, würde ich gern diese Redundanz auflösen indem ich folgendes mache:
String optionList = ... p.fit_textline(text, 0.0, 0.0, optionList); ... p.fit_textline(text, 0.0, 0.0, optionList); ... etc.
Soweit so gut. Ich schaffe es aber nicht, aus dieser Parameterliste einen String zu machen. Mein Versuch sieht so aus:
String optionList = "boxsize = {\" + boxWidth + \" \" + boxHeight + \"} " + "embedding = true " + "encoding = unicode " + "fillcolor = {cmyk \" + textColor.cyan + \" \" + textColor.magenta + \" \" + textColor.yellow + \" \" + textColor.key + \"} " + "fitmethod = meet " + "fontname = input/fonts/\" + fontName + \" " + "fontsize = \" + banderoleWidth + \" " + "margin = \" + banderoleWidth / 5 + \" " + "position = {center center}\"";
Dabei bekomme ich eine Exception: "com.pdflib.PDFlibException: Option 'boxsize' has too many values (> 2)"
Das Problem ist denke ich, dass Variablen, die in der Parameterliste vorkommen, wie z.B. boxWidth und boxHeight, zum Zeitpunkt der Definition von optionList noch nicht feststehen.
Ich möchte aber optionList so definieren, dass dieser String beim Aufruf von fit_textline genau so interpretiert wird, wie die ausgeschriebene Version ganz oben, nämlich das der dann gültige Wert von boxWidth, boxHeight etc. eingesetzt wird. Ist das überhaupt möglich?
Ich hoffe ich habe es geschafft, mein Problem verständlich zu erklären...
-
In deiner ersten Variante enthält dein String die Werte der entsprechenden Variablen. In Deiner zweiten Variante enthält der String nur den Namen der Variablen, da du die Anführungszeichen maskiert hast. Die Methode die das ganze verarbeitet muss also erstmal den Wert aus der Variablen abrufen anstatt in einfach aus dem String zu lesen.
-
Wieso Quotest du die "
"boxsize = {\" + boxWidth + \" \" + boxHeight + \"} " +
ist ein einziger String. Java ist kein PHP wo man Variablen im String haben kann. Bei sovielen String-Zusammenführungen solltest du aber lieber StringBuilder verwenden.
Oder besser verwendte PrintStream#printf.
int boxWidth = 5; int boxHeight = 5; // ... out.printf("boxsize={%d, %d} ...", boxWidth, boxHeight, ...);
-
@ Tolpan
Ich weiß, mir ist aber noch nicht klar, wie ich das Problem lösen kann.
@ DEvent
out.printf sieht so aus, als könnte es mein Problem lösen. Es gibt aber ein PrintStream-Objekt zurück und keinen String.
Ein weiteres Problem ist, dass optionList zu Beginn der Methode definiert werden muss, die einzelnen Variablenwerte aber erst zu einem späteren Zeitpunkt feststehen.
-
Schaut dir mal String.format(...) an.
-
Okay, String.format() gibt einen String zurück; das löst immerhin schon mal das erste Problem.
Das zweite Problem bleibt aber bestehen:
Zu Beginn der Methode will ich optionList definieren, aber mehrere Variablen wie z.B. boxWidth und boxHeight werden erst später definiert:
*METHODENANFANG
...
optionList = [String inkl. boxWidth, boxHeight etc.]
...
Definition von boxWidth, boxHeight etc.
...
fit_textline(bla, bla, bla, optionList);
...
fit_textline(bla, bla, bla, optionList);
...
fit_textline(bla, bla, bla, optionList);
...
METHODENENDE*
Die einzige Lösung die mir da einfällt ist eine eigene Methode zu schreiben, die den langen fit_textline-Aufruf kapselt und an dessen Stelle aufgerufen wird:
private void fit_banderole() { p.fit_textline(text, 0.0, 0.0, "boxsize = {" + boxWidth + " " + boxHeight + "} " + "embedding = true " + "encoding = unicode " + "fillcolor = {cmyk " + textColor.cyan + " " + textColor.magenta + " " + textColor.yellow + " " + textColor.key + "} " + "fitmethod = meet " + "fontname = input/fonts/" + fontName + " " + "fontsize = " + banderoleWidth + " " + "margin = " + banderoleWidth / 5 + " " + "position = {center center}"); }
-
Nein, halt. Das funktioniert auch nicht so, da ich der Methode fit_banderole()
erst die Werte von boxWidth, boxHeight etc. als Argumete übergeben müsste.Und das würde die Sache so kompliziert machen, dass es keine Vereinfachung im Vergleich zu meinem jetzigen Vorgehen ist...
-
Was willst du denn genau damit ereichen? vielleicht gibts ja ne andere Möglichkeit die deinen Riesenstring überflüssig macht.
-
Ich will lediglich erreichen, dass ich nicht 8x innerhalb von ein und derselben Methode immer den genau gleichen und sehr langen Methodenaufruf stehen habe.
-
Warum speicherst du dann den einmal zusammengebastelten String nicht einfach und verwendest ihn dann immer wieder?
Oder ändern sich die Variablenwerte zwischen den Aufrufen immer wieder? Dann wirst du nicht drumherumkommen, den String immer wieder neu zusammenzubauen. Du könntest das höchstens in eine eigene Klasse packen, um Coderedundanzen abzubauen.
-
Ja, die Variablenwerte ändern sich zwischen den Aufrufen.
-
Dann würde ich das, wie gesagt, mit einer eigenen Builder-Klasse lösen:
class OptionsBuilder { private int boxWidth; private int boxHeight; // + andere Parameter... public void setBoxWidth(int boxWidth) { this.boxWidth = boxWidth; } // + andere Setter... public String build() { return "boxsize = {" + boxWidth + " " + boxHeight + "} " + ... } }
Aufruf:
... OptionsBuilder opts = new OptionsBuilder(); p.fit_textline(text, 0.0, 0.0, opts.build()); opts.setBoxWidth(500); p.fit_textline(text, 0.0, 0.0, opts.build()); ...
-
Tolle Lösung, dankeschön!