Separation of concerns between SWTConsole and Key listener.

made an interface for the listener to use. Added test of the listener
effects.

Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
Emmanuel Bigeon 2016-11-19 17:36:51 -05:00
parent c2fa0f2c0b
commit a70be63894
5 changed files with 252 additions and 21 deletions

View File

@ -47,7 +47,7 @@
<parent> <parent>
<groupId>fr.bigeon</groupId> <groupId>fr.bigeon</groupId>
<artifactId>ebigeon-config</artifactId> <artifactId>ebigeon-config</artifactId>
<version>1.7.0</version> <version>1.7.1</version>
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>

View File

@ -0,0 +1,59 @@
/*
* Copyright E. Bigeon (2015)
*
* emmanuel@bigeon.fr
*
* This software is a computer program whose purpose is to
* provide a swt window for console applications.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
/**
* gclc-swt:fr.bigeon.gclc.swt.ConsoleDelayIO.java
* Created on: Nov 19, 2016
*/
package fr.bigeon.gclc.swt;
import fr.bigeon.gclc.manager.ConsoleManager;
/**
* <p>
* TODO
*
* @author Emmanuel Bigeon
*
*/
public interface ConsoleDelayIO extends ConsoleManager {
/** Actually send the input as the prompt next input. */
void validateInput();
/** @param input the input to set */
void setInput(String input);
/** @return the non validated input */
String getInput();
}

View File

@ -41,7 +41,6 @@ package fr.bigeon.gclc.swt;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Text;
import fr.bigeon.collections.ArrayRibbon; import fr.bigeon.collections.ArrayRibbon;
import fr.bigeon.collections.Ribbon; import fr.bigeon.collections.Ribbon;
@ -53,21 +52,19 @@ public final class HistoryTextKeyListener extends KeyAdapter {
/** The size of commands history */ /** The size of commands history */
private static final int DEFAULT_HISTORY_SIZE = 10; private static final int DEFAULT_HISTORY_SIZE = 10;
/** The empty string constant */
private static final String EMPTY = ""; //$NON-NLS-1$
/** The history ribbon */ /** The history ribbon */
private final Ribbon<String> commands; private final Ribbon<String> commands;
/** The current index in history search */ /** The current index in history search */
private int currentIndex = 0; private int currentIndex = 0;
/** The console to write the commands in */
private final Text consoleInput;
/** The console to notify of command validation */ /** The console to notify of command validation */
private final SWTConsole console; private final ConsoleDelayIO console;
/** @param console the console /** @param console the console delayed */
* @param consoleInput the text to write commands in */ public HistoryTextKeyListener(ConsoleDelayIO console) {
public HistoryTextKeyListener(SWTConsole console, Text consoleInput) {
super(); super();
this.console = console; this.console = console;
this.consoleInput = consoleInput;
this.commands = new ArrayRibbon<>(DEFAULT_HISTORY_SIZE); this.commands = new ArrayRibbon<>(DEFAULT_HISTORY_SIZE);
} }
@ -81,7 +78,10 @@ public final class HistoryTextKeyListener extends KeyAdapter {
public void pressedKeyCode(int keyCode) { public void pressedKeyCode(int keyCode) {
// Enter validates the command if prompting // Enter validates the command if prompting
if (keyCode == '\r') { if (keyCode == '\r') {
commands.add(consoleInput.getText()); String input = console.getInput();
if (!input.isEmpty()) {
commands.add(input);
}
console.validateInput(); console.validateInput();
currentIndex = -1; currentIndex = -1;
} }
@ -91,20 +91,18 @@ public final class HistoryTextKeyListener extends KeyAdapter {
currentIndex < commands.size() - 1) { currentIndex < commands.size() - 1) {
currentIndex++; currentIndex++;
String cmd = commands.get(commands.size() - currentIndex - 1); String cmd = commands.get(commands.size() - currentIndex - 1);
consoleInput.setText(cmd); console.setInput(cmd);
consoleInput.setSelection(cmd.length());
} }
// Lower arrow retrieves next commands // Lower arrow retrieves next commands
if (keyCode == SWT.ARROW_DOWN) { if (keyCode == SWT.ARROW_DOWN) {
if (currentIndex == 0) { if (currentIndex == 0) {
currentIndex--; currentIndex--;
consoleInput.setText(new String()); console.setInput(EMPTY);
} else if (currentIndex > 0) { } else if (currentIndex > 0) {
String cmd = commands String cmd = commands
.get(commands.size() - (--currentIndex) - 1); .get(commands.size() - (--currentIndex) - 1);
consoleInput.setText(cmd); console.setInput(cmd);
consoleInput.setSelection(cmd.length());
} }
} }
} }

View File

@ -53,13 +53,12 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Text;
import fr.bigeon.gclc.ConsoleApplication; import fr.bigeon.gclc.ConsoleApplication;
import fr.bigeon.gclc.manager.ConsoleManager;
/** A SWT component to connect to gclc {@link ConsoleApplication} /** A SWT component to connect to gclc {@link ConsoleApplication}
* <p> * <p>
* *
* @author Emmanuel Bigeon */ * @author Emmanuel Bigeon */
public class SWTConsole extends Composite implements ConsoleManager { public class SWTConsole extends Composite implements ConsoleDelayIO {
/** /**
* *
*/ */
@ -69,6 +68,8 @@ public class SWTConsole extends Composite implements ConsoleManager {
/** The class logger */ /** The class logger */
private static final Logger LOGGER = Logger private static final Logger LOGGER = Logger
.getLogger(SWTConsole.class.getName()); .getLogger(SWTConsole.class.getName());
/** The empty string constant */
private static final String EMPTY = ""; //$NON-NLS-1$
/** The console output text field */ /** The console output text field */
private final Text consoleOutput; private final Text consoleOutput;
/** The console input text field */ /** The console input text field */
@ -112,15 +113,15 @@ public class SWTConsole extends Composite implements ConsoleManager {
consoleInput = new Text(this, SWT.BORDER); consoleInput = new Text(this, SWT.BORDER);
consoleInput.setLayoutData( consoleInput.setLayoutData(
new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
consoleInput consoleInput.addKeyListener(new HistoryTextKeyListener(this));
.addKeyListener(new HistoryTextKeyListener(this, consoleInput));
} }
/** /**
* *
*/ */
protected void validateInput() { @Override
public void validateInput() {
Display.getDefault().syncExec(new Runnable() { Display.getDefault().syncExec(new Runnable() {
@SuppressWarnings("synthetic-access") @SuppressWarnings("synthetic-access")
@Override @Override
@ -143,7 +144,7 @@ public class SWTConsole extends Composite implements ConsoleManager {
public void run() { public void run() {
command = consoleInput.getText(); command = consoleInput.getText();
prompting = false; prompting = false;
consoleInput.setText(new String()); consoleInput.setText(EMPTY);
consoleOutput.append( consoleOutput.append(
CMD_PREFIX + command + System.lineSeparator()); CMD_PREFIX + command + System.lineSeparator());
} }
@ -336,4 +337,19 @@ public class SWTConsole extends Composite implements ConsoleManager {
validateInput(); validateInput();
} }
/* (non-Javadoc)
* @see fr.bigeon.gclc.swt.ConsoleDelayIO#setInput(java.lang.String) */
@Override
public void setInput(String input) {
consoleInput.setText(input);
consoleInput.setSelection(input.length());
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.swt.ConsoleDelayIO#getInput() */
@Override
public String getInput() {
return consoleInput.getText();
}
} }

View File

@ -0,0 +1,158 @@
/*
* Copyright E. Bigeon (2015)
*
* emmanuel@bigeon.fr
*
* This software is a computer program whose purpose is to
* provide a swt window for console applications.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
/**
* gclc-swt:fr.bigeon.gclc.swt.HistoryTextKeyListenerTest.java
* Created on: Nov 19, 2016
*/
package fr.bigeon.gclc.swt;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.eclipse.swt.SWT;
import org.junit.Test;
/** <p>
* TODO
*
* @author Emmanuel Bigeon */
public class HistoryTextKeyListenerTest {
/** Test method for
* {@link fr.bigeon.gclc.swt.HistoryTextKeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)}. */
@Test
public final void testKeyPressedKeyEvent() {
ConsoleDelayIO io = new ConsoleDelayIO() {
private String input = "";
@Override
public void setPrompt(String prompt) {
//
}
@Override
public String prompt(String message) throws IOException {
return null;
}
@Override
public String prompt() throws IOException {
return null;
}
@Override
public void println(String message) throws IOException {
//
}
@Override
public void println() throws IOException {
//
}
@Override
public void print(String text) throws IOException {
//
}
@Override
public boolean isClosed() {
return false;
}
@Override
public String getPrompt() {
return null;
}
@Override
public void close() throws IOException {
//
}
@Override
public void validateInput() {
input = "";
}
@Override
public void setInput(String input) {
this.input = input;
}
@Override
public String getInput() {
return input;
}
};
HistoryTextKeyListener listener = new HistoryTextKeyListener(io);
// no effects
assertEquals("", io.getInput());
listener.pressedKeyCode(SWT.ARROW_UP);
assertEquals("", io.getInput());
listener.pressedKeyCode(SWT.ARROW_DOWN);
assertEquals("", io.getInput());
listener.pressedKeyCode('\r');
assertEquals("", io.getInput());
io.setInput("cmd arg");
listener.pressedKeyCode(SWT.ARROW_UP);
assertEquals("cmd arg", io.getInput());
listener.pressedKeyCode(SWT.ARROW_DOWN);
assertEquals("cmd arg", io.getInput());
listener.pressedKeyCode('\r');
assertEquals("", io.getInput());
io.setInput("cmd arg2");
listener.pressedKeyCode(SWT.ARROW_UP);
assertEquals("cmd arg", io.getInput());
listener.pressedKeyCode(SWT.ARROW_DOWN);
assertEquals("", io.getInput());
io.setInput("cmd arg2");
listener.pressedKeyCode('\r');
assertEquals("", io.getInput());
listener.pressedKeyCode(SWT.ARROW_UP);
assertEquals("cmd arg2", io.getInput());
listener.pressedKeyCode(SWT.ARROW_UP);
assertEquals("cmd arg", io.getInput());
listener.pressedKeyCode(SWT.ARROW_UP);
assertEquals("cmd arg", io.getInput());
listener.pressedKeyCode(SWT.ARROW_DOWN);
assertEquals("cmd arg2", io.getInput());
}
}