diff --git a/src/main/java/de/neemann/digital/gui/components/terminal/CharDeleter.java b/src/main/java/de/neemann/digital/gui/components/terminal/CharDeleter.java new file mode 100644 index 000000000..833319228 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/terminal/CharDeleter.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.gui.components.terminal; + +/** + * Used to delete a char in a string and keep track of the cursor position + */ +public class CharDeleter { + private String text; + private int pos; + + /** + * Creaztes a new instance + * + * @param text the text + * @param pos the cursor position + */ + public CharDeleter(String text, int pos) { + this.text = text; + this.pos = pos; + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @return the cursor position + */ + public int getPos() { + return pos; + } + + /** + * deletes the last char + * + * @return this for chained calls + */ + public CharDeleter delete() { + final int len = text.length(); + if (len > 0) { + char last = text.charAt(len - 1); + text = text.substring(0, len - 1); + pos--; + + if (last == '\n') { + pos = 0; + int p = len - 2; + while (p >= 0 && text.charAt(p) != '\n') { + pos++; + p--; + } + } + } + return this; + } +} diff --git a/src/main/java/de/neemann/digital/gui/components/terminal/TerminalDialog.java b/src/main/java/de/neemann/digital/gui/components/terminal/TerminalDialog.java index 5e6ee2d38..16619adbd 100644 --- a/src/main/java/de/neemann/digital/gui/components/terminal/TerminalDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/terminal/TerminalDialog.java @@ -66,16 +66,28 @@ public class TerminalDialog extends JDialog { * @param value the character */ public void addChar(char value) { - if (value == 13 || value == 10) { - pos = 0; - textArea.append("\n"); - } else { - textArea.append("" + value); - pos++; - if (pos == width) { + switch (value) { + case 13: + case 10: pos = 0; textArea.append("\n"); - } + break; + case 8: + CharDeleter cd = new CharDeleter(textArea.getText(), pos).delete(); + textArea.setText(cd.getText()); + pos = cd.getPos(); + break; + case 12: + pos = 0; + textArea.setText(""); + break; + default: + textArea.append("" + value); + pos++; + if (pos == width) { + pos = 0; + textArea.append("\n"); + } } } } diff --git a/src/test/java/de/neemann/digital/gui/components/terminal/CharDeleterTest.java b/src/test/java/de/neemann/digital/gui/components/terminal/CharDeleterTest.java new file mode 100644 index 000000000..df2fcfe48 --- /dev/null +++ b/src/test/java/de/neemann/digital/gui/components/terminal/CharDeleterTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.gui.components.terminal; + +import junit.framework.TestCase; + +public class CharDeleterTest extends TestCase { + + public void testSimple() { + CharDeleter cd = new CharDeleter("test", 4).delete(); + assertEquals("tes", cd.getText()); + assertEquals(3, cd.getPos()); + } + + public void testLineFeed1() { + CharDeleter cd = new CharDeleter("\n\n", 0).delete(); + assertEquals("\n", cd.getText()); + assertEquals(0, cd.getPos()); + } + + public void testLineFeed2() { + CharDeleter cd = new CharDeleter("\ntest\n", 0).delete(); + assertEquals("\ntest", cd.getText()); + assertEquals(4, cd.getPos()); + } + + public void testLineFeed3() { + CharDeleter cd = new CharDeleter("test\n", 0).delete(); + assertEquals("test", cd.getText()); + assertEquals(4, cd.getPos()); + } + + public void testLineFeed4() { + CharDeleter cd = new CharDeleter("test\ntest\n", 0).delete(); + assertEquals("test\ntest", cd.getText()); + assertEquals(4, cd.getPos()); + } + +} \ No newline at end of file