diff --git a/src/main/java/de/neemann/gui/ErrorMessage.java b/src/main/java/de/neemann/gui/ErrorMessage.java
index 6ffdb8048..49e17d394 100644
--- a/src/main/java/de/neemann/gui/ErrorMessage.java
+++ b/src/main/java/de/neemann/gui/ErrorMessage.java
@@ -63,7 +63,9 @@ public class ErrorMessage implements Runnable {
* @return this for call chaining
*/
public ErrorMessage show(Component parent) {
- JOptionPane.showMessageDialog(parent, message.toString(), Lang.get("error"), JOptionPane.ERROR_MESSAGE);
+ JOptionPane.showMessageDialog(parent,
+ new LineBreaker(120).toHTML().preserveContainedLineBreaks().breakLines(message.toString()),
+ Lang.get("error"), JOptionPane.ERROR_MESSAGE);
return this;
}
diff --git a/src/main/java/de/neemann/gui/LineBreaker.java b/src/main/java/de/neemann/gui/LineBreaker.java
new file mode 100644
index 000000000..a5ae7394d
--- /dev/null
+++ b/src/main/java/de/neemann/gui/LineBreaker.java
@@ -0,0 +1,137 @@
+package de.neemann.gui;
+
+/**
+ * Used to break lines.
+ * Created by hneemann on 29.04.17.
+ */
+public class LineBreaker {
+ private static final int DEF_COLS = 70;
+
+ private final String label;
+ private final int indent;
+ private final int cols;
+ private final StringBuilder outText;
+ private boolean isFirst;
+ private int pos;
+ private boolean preserveLineBreaks = false;
+ private boolean toHTML = false;
+ private boolean containsLineBreak = false;
+
+ /**
+ * Creates a new instance
+ */
+ public LineBreaker() {
+ this(DEF_COLS);
+ }
+
+ /**
+ * Creates a new instance
+ *
+ * @param cols number of columns to use
+ */
+ public LineBreaker(int cols) {
+ this("", 0, cols);
+ }
+
+ /**
+ * Creates a new instance
+ *
+ * @param label the lable to use in the first line
+ * @param indent columns to indent
+ * @param cols number of columns to use
+ */
+ public LineBreaker(String label, int indent, int cols) {
+ this.label = label;
+ this.indent = indent;
+ this.cols = cols;
+ outText = new StringBuilder(label);
+ isFirst = true;
+ }
+
+ /**
+ * Breaks the line
+ *
+ * @param text the text to handle
+ * @return the text containing the line breaks
+ */
+ public String breakLines(String text) {
+ if (text == null)
+ return null;
+
+ for (int i = 0; i < indent - label.length(); i++)
+ outText.append(" ");
+
+ StringBuilder word = new StringBuilder();
+ pos = indent;
+ for (int i = 0; i < text.length(); i++) {
+ char c = text.charAt(i);
+ switch (c) {
+ case '\n':
+ if (preserveLineBreaks) {
+ addWord(word);
+ lineBreak();
+ isFirst = true;
+ break;
+ }
+ case '\r':
+ case ' ':
+ addWord(word);
+ break;
+ default:
+ word.append(c);
+ }
+ }
+ addWord(word);
+
+ String ret = outText.toString();
+ if (containsLineBreak && toHTML)
+ ret = "" + ret.replace("\n", "
") + "";
+
+ return ret;
+ }
+
+ private void addWord(StringBuilder word) {
+ if (word.length() > 0) {
+ if (pos + (isFirst ? word.length() : word.length() + 1) > cols) {
+ lineBreak();
+ } else {
+ if (!isFirst) {
+ outText.append(" ");
+ pos++;
+ }
+ }
+ outText.append(word);
+ pos += word.length();
+ word.setLength(0);
+ isFirst = false;
+ }
+ }
+
+ private void lineBreak() {
+ outText.append('\n');
+ for (int j = 0; j < indent; j++)
+ outText.append(" ");
+ pos = indent;
+ containsLineBreak = true;
+ }
+
+ /**
+ * Preserves the contained line breaks
+ *
+ * @return this for chained calls
+ */
+ public LineBreaker preserveContainedLineBreaks() {
+ this.preserveLineBreaks = true;
+ return this;
+ }
+
+ /**
+ * Returns an HTML string
+ *
+ * @return this for chained calls
+ */
+ public LineBreaker toHTML() {
+ this.toHTML = true;
+ return this;
+ }
+}
diff --git a/src/main/java/de/neemann/gui/StringUtils.java b/src/main/java/de/neemann/gui/StringUtils.java
index 484bfb002..dd9ff32f6 100644
--- a/src/main/java/de/neemann/gui/StringUtils.java
+++ b/src/main/java/de/neemann/gui/StringUtils.java
@@ -5,7 +5,6 @@ package de.neemann.gui;
*/
public final class StringUtils {
- private static final int DEF_COLS = 70;
private StringUtils() {
}
@@ -53,112 +52,13 @@ public final class StringUtils {
/**
* Formats text to html if it contains line breaks.
- * Short texts are unchanged.
+ * Short texts are unchanged. Ignores the containing line breaks.
*
* @param text the text
* @return the unchanged text or a HTML segment
*/
public static String textToHTML(String text) {
- String toolTipText = StringUtils.breakLines(text);
- if (toolTipText == null)
- return null;
-
- if (toolTipText.indexOf('\n') >= 0)
- toolTipText = "" + toolTipText.replace("\n", "
") + "";
- return toolTipText;
- }
-
-
- /**
- * Breaks a string separate lines, all multiple spaces and line breaks are removed.
- * calls {@code breakLines(text, 60)}.
- *
- * @param text the text to format
- * @return the formatted text
- */
- public static String breakLines(String text) {
- return breakLines(text, DEF_COLS);
- }
-
- /**
- * Breaks a string into separate lines, all multiple blanks and line breaks are removed.
- *
- * @param text the text to format
- * @param cols the number of columns
- * @return the formatted text
- */
- public static String breakLines(String text, int cols) {
- return breakLinesLabel("", 0, text, cols);
- }
-
- /**
- * Format a text width indentation
- *
- * @param label label to print in front of the text
- * @param indent cols to indent the label
- * @param text the text
- * @return the formatted text
- */
- public static String breakLinesLabel(String label, int indent, String text) {
- return breakLinesLabel(label, indent, text, DEF_COLS);
- }
-
- /**
- * Format a text width indentation
- *
- * @param label label to print in front of the text
- * @param indent cols to indent the label
- * @param text the text
- * @param cols the number of columns
- * @return the formatted text
- */
- public static String breakLinesLabel(String label, int indent, String text, int cols) {
- if (text == null)
- return null;
-
- StringBuilder outText = new StringBuilder(label);
- for (int i = 0; i < indent - label.length(); i++)
- outText.append(" ");
-
- StringBuilder word = new StringBuilder();
- boolean isFirst = true;
- int pos = indent;
- for (int i = 0; i < text.length(); i++) {
- char c = text.charAt(i);
- switch (c) {
- case '\n':
- case '\r':
- case ' ':
- pos = addWord(indent, cols, outText, word, pos, isFirst);
- isFirst = false;
- break;
- default:
- word.append(c);
- }
- }
- addWord(indent, cols, outText, word, pos, isFirst);
- return outText.toString();
- }
-
- private static int addWord(int indent, int cols, StringBuilder outText, StringBuilder word, int pos, boolean isFirst) {
- if (word.length() > 0) {
- if (pos + (isFirst ? word.length() : word.length() + 1) > cols) {
- outText.append('\n');
- for (int j = 0; j < indent; j++)
- outText.append(" ");
-
- pos = indent;
- } else {
- if (!isFirst) {
- outText.append(" ");
- pos++;
- }
- }
- outText.append(word);
- pos += word.length();
- word.setLength(0);
- }
- return pos;
+ return new LineBreaker().toHTML().breakLines(text);
}
}
diff --git a/src/test/java/de/neemann/gui/LineBreakerTest.java b/src/test/java/de/neemann/gui/LineBreakerTest.java
new file mode 100644
index 000000000..fb483330c
--- /dev/null
+++ b/src/test/java/de/neemann/gui/LineBreakerTest.java
@@ -0,0 +1,37 @@
+package de.neemann.gui;
+
+import junit.framework.TestCase;
+
+/**
+ * Created by hneemann on 29.04.17.
+ */
+public class LineBreakerTest extends TestCase {
+
+ public void testBreakLines() throws Exception {
+ assertEquals("this is a test string", new LineBreaker(60).breakLines("this \n\n is \n a test \n\r string"));
+ assertEquals("this is a test\nstring", new LineBreaker(14).breakLines("this \n\n is \n a test \n\r string"));
+ assertEquals("This is a test string. This\n" +
+ "is a test string. This is a\n" +
+ "test string.", new LineBreaker(27).breakLines("This is a test string. This is a test string. This is a test string."));
+ assertEquals("this is\naWordThatIsFarToLongToFitInASingleLine\nThis is a test string", new LineBreaker(21).breakLines("this is aWordThatIsFarToLongToFitInASingleLine This is a test string"));
+ }
+
+ public void testBreakLinesLabel() throws Exception {
+ assertEquals("a) This is a test string. This\n" +
+ " is a test string. This is a\n" +
+ " test string.", new LineBreaker("a)", 3, 30).breakLines("This is a test string. This is a test string. This is a test string."));
+ }
+
+
+ public void testBreakLinesPreserve() throws Exception {
+ assertEquals("this is a\ntest string", new LineBreaker(60).preserveContainedLineBreaks().breakLines("this is a\n test string"));
+ assertEquals("this is a\ntest string. This is\na test string.", new LineBreaker(20).preserveContainedLineBreaks().breakLines("this is a\n test string. This is a test string."));
+ }
+
+ public void testBreakLinesHTML() throws Exception {
+ assertEquals("this is a test string", new LineBreaker(60).toHTML().breakLines("this is a\n test string"));
+ assertEquals("this is a
test string", new LineBreaker(60).toHTML().preserveContainedLineBreaks().breakLines("this is a\n test string"));
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/test/java/de/neemann/gui/StringUtilsTest.java b/src/test/java/de/neemann/gui/StringUtilsTest.java
deleted file mode 100644
index d97be4f8f..000000000
--- a/src/test/java/de/neemann/gui/StringUtilsTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package de.neemann.gui;
-
-import junit.framework.TestCase;
-
-/**
- * Created by hneemann on 29.10.16.
- */
-public class StringUtilsTest extends TestCase {
-
- public void testBreakLines() throws Exception {
- assertEquals("this is a test string", StringUtils.breakLines("this \n\n is \n a test \n\r string", 60));
- assertEquals("this is a test\nstring", StringUtils.breakLines("this \n\n is \n a test \n\r string", 14));
- assertEquals("This is a test string. This\n" +
- "is a test string. This is a\n" +
- "test string.", StringUtils.breakLines("This is a test string. This is a test string. This is a test string.", 27));
- assertEquals("this is\naWordThatIsFarToLongToFitInASingleLine\nThis is a test string", StringUtils.breakLines("this is aWordThatIsFarToLongToFitInASingleLine This is a test string", 21));
- }
-
- public void testBreakLinesLabel() throws Exception {
- assertEquals("a) This is a test string. This\n" +
- " is a test string. This is a\n" +
- " test string.", StringUtils.breakLinesLabel("a)", 3, "This is a test string. This is a test string. This is a test string.", 30));
- }
-
-}
\ No newline at end of file