Skip to content

Commit 4e43a35

Browse files
committed
add withProperties methods
1 parent a05d6df commit 4e43a35

File tree

8 files changed

+188
-101
lines changed

8 files changed

+188
-101
lines changed

dist/xbin/Cuboid.properties

+9-10
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,31 @@
22

33
textio.user.interrupt.key = ctrl Q
44

5-
textio.custom.default.color = white
6-
textio.custom.default.bgcolor = black
5+
textio.custom.neutral.prompt.color = white
6+
textio.custom.neutral.prompt.bgcolor = black
7+
textio.custom.neutral.input.color = white
8+
textio.custom.neutral.input.bgcolor = black
79

8-
textio.custom.title.color = black
9-
textio.custom.title.bgcolor = green
10-
textio.custom.title.bold = true
11-
web.custom.title.style = fancy-border
10+
textio.custom.title.prompt.color = black
11+
textio.custom.title.prompt.bgcolor = green
12+
textio.custom.title.prompt.bold = true
13+
textio.custom.title.prompt.style.class = fancy-border
1214

1315
textio.custom.length.prompt.color = cyan
1416
textio.custom.length.prompt.bgcolor = black
1517
textio.custom.length.prompt.italic = true
1618
textio.custom.length.input.color = blue
1719
textio.custom.length.input.bold = true
18-
web.custom.length.style =
1920

2021
textio.custom.width.prompt.color = green
2122
textio.custom.width.prompt.bgcolor = black
22-
textio.custom.width.underline = true
23+
textio.custom.width.prompt.underline = true
2324
textio.custom.width.input.color = yellow
2425
textio.custom.width.input.italic = true
25-
web.custom.width.style =
2626

2727
textio.custom.height.prompt.color = magenta
2828
textio.custom.height.prompt.bgcolor = black
2929
textio.custom.height.input.color = red
3030
textio.custom.height.input.italic = true
3131
textio.custom.height.input.underline = true
32-
web.custom.height.style =
3332

doc/user_guide.adoc

+77-4
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,56 @@ link:{blob-root}/text-io-demo/src/main/java/org/beryx/textio/demo[source code]
329329
and the link:{blob-root}/dist/xbin[configuration files]
330330
of the https://github.com/beryx/text-io/releases/download/v{project-version}/textio-demo-{project-version}.zip[demo application].
331331

332+
[[terminal_temporary_props]]
333+
=== TextTerminal temporary properties
334+
335+
Sometimes you want to temporarily change some TextTerminal properties and revert them to their previous values after a couple of operations.
336+
You can achieve this by passing the sequence of operations to be executed with modified properties as argument to the
337+
link:javadoc/org/beryx/textio/TextTerminal.html#executeWithPropertiesConfigurator-java.util.function.Consumer-java.util.function.Consumer-[executeWithPropertiesConfigurator()]
338+
method, as shown in the example below.
339+
[source,java]
340+
----
341+
textTerminal.getProperties().setPromptColor("cyan");
342+
textTerminal.println("1. Choose the desired hard drive.");
343+
textTerminal.executeWithPropertiesConfigurator(
344+
props -> props.setPromptColor("red"),
345+
t -> t.println("2. Backup all your data."));
346+
textTerminal.println("3. Start the formatting process.");
347+
----
348+
The second message will appear in red, while the other two will be printed in cyan.
349+
350+
The code above uses hard-coded property values.
351+
A more elegant solution is to specify these values in the `textio.properties` file.
352+
TextTerminal offers the
353+
link:javadoc/org/beryx/textio/TextTerminal.html#executeWithPropertiesPrefix-java.util.function.Consumer-java.util.function.Consumer-[executeWithPropertiesConfigurator()]
354+
convenience method to help you accomplish this task.
355+
356+
Consider the code below:
357+
[source,java]
358+
----
359+
textTerminal.println("1. Choose the desired hard drive.");
360+
textTerminal.executeWithPropertiesPrefix("warn",
361+
t -> t.println("2. Backup all your data."));
362+
textTerminal.println("3. Start the formatting process.");
363+
----
364+
and let's assume that your `textio.properties` contains:
365+
[source]
366+
----
367+
textio.prompt.color = cyan
368+
textio.warn.prompt.color = red
369+
----
370+
Then, the second message will appear in red, while the other two will be printed in cyan.
371+
372+
TIP: Look at the source code of
373+
link:{blob-root}/text-io-demo/src/main/java/org/beryx/textio/demo/app/Cuboid.java[Cuboid.java]
374+
for an example of using temporary TextTerminal properties.
375+
332376
[[input_reader_props]]
333377
=== InputReader-specific properties
334378

335-
Sometimes you want to change some TextTerminal properties for the next read operation, but want to revert to the previous property values at the end of this read operation.
336-
You can achieve this by configuring InputReader-specific properties via the
337-
link:javadoc/org/beryx/textio/InputReader.html#withPropertiesConfigurator-java.util.function.Consumer-withPropertiesConfigurator[withPropertiesConfigurator()]
338-
method, as shown in the example below.
379+
If you want to apply some temporary TextTerminal properties only during the next read operation, you can call the
380+
link:javadoc/org/beryx/textio/InputReader.html#withPropertiesConfigurator-java.util.function.Consumer-[withPropertiesConfigurator()]
381+
method of your InputReader, as shown in the example below.
339382
[source,java]
340383
----
341384
textIO.getTextTerminal().getProperties().setPromptColor("cyan");
@@ -347,6 +390,36 @@ String directory = textIO.newStringInputReader().read("Home directory");
347390
----
348391
The question _"Erase all data?"_ will appear in red, while _"User name"_ and _"Home directory"_ will be printed in cyan.
349392

393+
The code above uses hard-coded property values.
394+
A more elegant solution is to specify these values in the `textio.properties` file.
395+
InputReader offers the
396+
link:javadoc/org/beryx/textio/InputReader.html#withPropertiesPrefix-java.lang.String-[withPropertiesPrefix()]
397+
convenience method to help you accomplish this task.
398+
399+
Consider the code below:
400+
[source,java]
401+
----
402+
String user = textIO.newStringInputReader().read("User name");
403+
textIO.newBooleanInputReader()
404+
.withPropertiesPrefix("warn")
405+
.read("Erase all data?");
406+
String directory = textIO.newStringInputReader().read("Home directory");
407+
----
408+
and let's assume that your `textio.properties` contains:
409+
[source]
410+
----
411+
textio.prompt.color = green
412+
textio.input.color = yellow
413+
textio.warn.prompt.color = red
414+
textio.warn.input.color = orange
415+
----
416+
Then, the question _"Erase all data?"_ will appear in red and its corresponding user input in orange.
417+
For the other two read operations the questions will be displayed in green and the user input in yellow.
418+
419+
TIP: Look at the source code of
420+
link:{blob-root}/text-io-demo/src/main/java/org/beryx/textio/demo/app/Cuboid.java[Cuboid.java]
421+
for an example of using InputReader-specific properties.
422+
350423

351424
[[web_text_term]]
352425
== Using the WebTextTerminal

text-io-demo/src/main/java/org/beryx/textio/demo/app/Cuboid.java

+12-67
Original file line numberDiff line numberDiff line change
@@ -29,94 +29,39 @@ public static void main(String[] args) {
2929
new Cuboid().accept(textIO, null);
3030
}
3131

32-
private static class TextProps {
33-
private final String prefix;
34-
private final TerminalProperties<?> props;
35-
36-
public final String color;
37-
public final String bgcolor;
38-
public final boolean bold;
39-
public final boolean italic;
40-
public final boolean underline;
41-
public final String style;
42-
43-
public TextProps(TerminalProperties<?> props, String prefix) {
44-
this.props = props;
45-
this.prefix = prefix;
46-
color = props.getString(propName("color"));
47-
bgcolor = props.getString(propName("bgcolor"));
48-
bold = props.getBoolean(propName("bold"), false);
49-
italic = props.getBoolean(propName("italic"), false);
50-
underline = props.getBoolean(propName("underline"), false);
51-
style = props.getString(propName("style"));
52-
}
53-
54-
private String propName(String name) {
55-
return "custom." + prefix + "." + name;
56-
}
57-
58-
public void configurePrompt() {
59-
if(color != null) {
60-
props.setPromptColor(color);
61-
}
62-
if(bgcolor != null) {
63-
props.setPromptBackgroundColor(bgcolor);
64-
}
65-
props.setPromptBold(bold);
66-
props.setPromptItalic(italic);
67-
props.setPromptUnderline(underline);
68-
props.put(PropertiesConstants.PROP_PROMPT_STYLE_CLASS, style);
69-
}
70-
71-
public void configureInput() {
72-
if(color != null) {
73-
props.setInputColor(color);
74-
}
75-
if(bgcolor != null) {
76-
props.setInputBackgroundColor(bgcolor);
77-
}
78-
props.setInputBold(bold);
79-
props.setInputItalic(italic);
80-
props.setInputUnderline(underline);
81-
props.put(PropertiesConstants.PROP_INPUT_STYLE_CLASS, style);
82-
}
83-
}
84-
8532
@Override
8633
public void accept(TextIO textIO, RunnerData runnerData) {
8734
TextTerminal<?> terminal = textIO.getTextTerminal();
8835
String initData = (runnerData == null) ? null : runnerData.getInitData();
8936
AppUtil.printGsonMessage(terminal, initData);
9037

91-
TerminalProperties<?> props = terminal.getProperties();
92-
93-
new TextProps(props, "title").configurePrompt();
94-
terminal.println("Cuboid dimensions");
38+
terminal.executeWithPropertiesPrefix("custom.title", t -> t.print("Cuboid dimensions: "));
39+
terminal.println();
9540

96-
new TextProps(props, "length.prompt").configurePrompt();
97-
new TextProps(props, "length.input").configureInput();
9841
double length = textIO.newDoubleInputReader()
9942
.withMinVal(0.0)
43+
.withPropertiesPrefix("custom.length")
10044
.read("Length");
10145

102-
new TextProps(props, "width.prompt").configurePrompt();
103-
new TextProps(props, "width.input").configureInput();
10446
double width = textIO.newDoubleInputReader()
10547
.withMinVal(0.0)
48+
.withPropertiesPrefix("custom.width")
10649
.read("Width");
10750

108-
new TextProps(props, "height.prompt").configurePrompt();
109-
new TextProps(props, "height.input").configureInput();
11051
double height = textIO.newDoubleInputReader()
11152
.withMinVal(0.0)
53+
.withPropertiesPrefix("custom.height")
11254
.read("Height");
11355

11456

115-
new TextProps(props, "title").configurePrompt();
116-
terminal.println("The volume of your cuboid is: " + length * width * height);
57+
terminal.executeWithPropertiesPrefix("custom.title",
58+
t -> t.print("The volume of your cuboid is: " + length * width * height));
59+
terminal.println();
11760

118-
new TextProps(props, "default").configurePrompt();
119-
textIO.newStringInputReader().withMinLength(0).read("\nPress enter to terminate...");
61+
textIO.newStringInputReader()
62+
.withMinLength(0)
63+
.withPropertiesPrefix("custom.neutral")
64+
.read("\nPress enter to terminate...");
12065
textIO.dispose();
12166
}
12267

Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
.fancy-border {
22
border-style: dashed;
33
border-color: orange;
4+
line-height: 2.0;
5+
font-size: 18px;
46
}

text-io/src/main/java/org/beryx/textio/InputReader.java

+30
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,36 @@ public B withPropertiesConfigurator(Consumer<TerminalProperties<?>> propertiesCo
267267
return (B)this;
268268
}
269269

270+
/** Convenience method that calls {@link #withPropertiesConfigurator(Consumer)}
271+
* with a configurator that takes all terminal properties with the given prefix
272+
* and applies them after stripping the prefix from their keys.
273+
* <br>For example, if {@code textio.properties} contains:
274+
* <pre>
275+
* textio.prompt.color = green
276+
* textio.input.color = yellow
277+
* textio.warn.prompt.color = red
278+
* textio.warn.input.color = orange
279+
* </pre>
280+
* then the following statement:
281+
* <pre>
282+
* textIO.newBooleanInputReader()
283+
* .withPropertiesPrefix("warn")
284+
* .read("Erase all data?");
285+
* </pre>
286+
* will display the question in red and the user input in orange.
287+
**/
288+
@SuppressWarnings("unchecked")
289+
public B withPropertiesPrefix(String prefix) {
290+
return withPropertiesConfigurator(t -> {
291+
Set<String> keys = t.getMatchingKeys(key -> key.startsWith(prefix + "."));
292+
int len = prefix.length() + 1;
293+
keys.forEach(key -> {
294+
String baseKey = key.substring(len);
295+
t.put(baseKey, t.getString(key));
296+
});
297+
});
298+
}
299+
270300
/**
271301
* @return true, if currently reading a list of values via {@link #readList(List)}
272302
*/

text-io/src/main/java/org/beryx/textio/TerminalProperties.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
import org.slf4j.Logger;
2020
import org.slf4j.LoggerFactory;
2121

22-
import java.util.ArrayList;
23-
import java.util.HashMap;
24-
import java.util.List;
25-
import java.util.Map;
22+
import java.util.*;
2623
import java.util.function.Function;
24+
import java.util.function.Predicate;
25+
import java.util.stream.Collectors;
2726

2827
import static org.beryx.textio.PropertiesConstants.*;
2928

@@ -161,6 +160,18 @@ public void putAll(Map<String, ? extends Object> map) {
161160
map.entrySet().forEach(entry -> put(entry.getKey(), entry.getValue()));
162161
}
163162

163+
public Set<String> getAllKeys() {
164+
return props.keySet();
165+
}
166+
167+
public Set<String> getMatchingKeys(String regex) {
168+
return getMatchingKeys(key -> key.matches(regex));
169+
}
170+
171+
public Set<String> getMatchingKeys(Predicate<String> keyFilter) {
172+
return props.keySet().stream().filter(keyFilter).collect(Collectors.toSet());
173+
}
174+
164175
/**
165176
* @return the value associated with the specified key.
166177
*/

0 commit comments

Comments
 (0)