From eae7e0d69f1f73ea30f3d92349673b593514c20b Mon Sep 17 00:00:00 2001 From: Emmanuel Bigeon Date: Thu, 10 May 2018 11:29:11 -0400 Subject: [PATCH] Fix prompting mechanics Signed-off-by: Emmanuel Bigeon --- .../java/fr/bigeon/gclc/swt/SWTConsole.java | 101 +++++++++++------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/gclc-swt/src/main/java/fr/bigeon/gclc/swt/SWTConsole.java b/gclc-swt/src/main/java/fr/bigeon/gclc/swt/SWTConsole.java index 70c5468..04af02a 100644 --- a/gclc-swt/src/main/java/fr/bigeon/gclc/swt/SWTConsole.java +++ b/gclc-swt/src/main/java/fr/bigeon/gclc/swt/SWTConsole.java @@ -60,28 +60,28 @@ import fr.bigeon.gclc.tools.StringProvider; public final class SWTConsole extends Composite implements ConsoleDelayIO, ConsoleInput, ConsoleOutput { /** The number of columns of the layout. */ - private static final int LAYOUT_NB_COLUMNS = 2; + private static final int LAYOUT_NB_COLUMNS = 2; /** The cmd prefix in the output console. */ - private static final String CMD_PREFIX = "[CMD] "; //$NON-NLS-1$ + private static final String CMD_PREFIX = "[CMD] "; //$NON-NLS-1$ /** The class logger. */ - private static final Logger LOGGER = Logger + private static final Logger LOGGER = Logger .getLogger(SWTConsole.class.getName()); /** The empty string constant. */ - private static final String EMPTY = ""; //$NON-NLS-1$ + private static final String EMPTY = ""; //$NON-NLS-1$ /** The console output text field. */ - private final Text consoleOutput; + private final Text consoleOutput; /** The console input text field. */ - private final Text consoleInput; + private final Text consoleInput; /** The prompt label. */ - private final Label lblPromptlabel; + private final Label lblPromptlabel; /** The prompt text. */ - private StringProvider prompt = new ConstantString("> "); //$NON-NLS-1$ + private StringProvider prompt = new ConstantString("> "); //$NON-NLS-1$ /** The command entered by the user. */ - private String command = null; + private String command = null; /** If the prompt should be active. */ - private boolean prompting = false; + private boolean prompting = false; /** The object for thread synchronization with the prompt. */ - private final Object promptLock = new Object(); + private final Object promptLock = new Object(); /** Create the composite. * @@ -92,18 +92,17 @@ public final class SWTConsole extends Composite setLayout(new GridLayout(LAYOUT_NB_COLUMNS, false)); - consoleOutput = new Text(this, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | - SWT.V_SCROLL | SWT.MULTI); - consoleOutput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, - LAYOUT_NB_COLUMNS, 1)); + consoleOutput = new Text(this, + SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI); + consoleOutput.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true, LAYOUT_NB_COLUMNS, 1)); consoleOutput.setRedraw(true); lblPromptlabel = new Label(this, SWT.NONE); lblPromptlabel.setText(prompt.apply()); consoleInput = new Text(this, SWT.BORDER); - consoleInput.setLayoutData( - new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + consoleInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); consoleInput.addKeyListener(new HistoryTextKeyListener(this)); } @@ -213,22 +212,24 @@ public final class SWTConsole extends Composite } try { Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") @Override public void run() { if (!consoleInput.isDisposed()) { consoleInput.setEnabled(true); lblPromptlabel.setText(prompt.apply()); + // relayout + SWTConsole.this.layout(); consoleInput.setFocus(); } } }); prompting = true; promptLock.notifyAll(); - promptLock.wait(); + while (prompting) { + promptLock.wait(); + } } catch (final InterruptedException e) { - LOGGER.log(Level.WARNING, - "Error in synchronization of prompting", e); //$NON-NLS-1$ + LOGGER.log(Level.WARNING, "Error in synchronization of prompting", e); //$NON-NLS-1$ command = null; Thread.currentThread().interrupt(); } @@ -240,13 +241,45 @@ public final class SWTConsole extends Composite } /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(long) - */ + * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(long) */ @Override public String prompt(final long timeout) throws IOException { - // TODO Auto-generated method stub - // return null; - throw new RuntimeException("Not implemented yet"); + synchronized (promptLock) { + if (isDisposed()) { + throw new IOException(); + } + try { + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + if (!consoleInput.isDisposed()) { + consoleInput.setEnabled(true); + lblPromptlabel.setText(prompt.apply()); + // relayout + SWTConsole.this.layout(); + consoleInput.setFocus(); + } + } + }); + prompting = true; + command = null; + promptLock.notifyAll(); + long start = System.currentTimeMillis(); + long cur = start; + while (prompting && start + timeout>cur) { + promptLock.wait((cur-start-timeout)/2); + cur = System.currentTimeMillis(); + } + } catch (final InterruptedException e) { + LOGGER.log(Level.WARNING, "Error in synchronization of prompting", e); //$NON-NLS-1$ + command = null; + Thread.currentThread().interrupt(); + } + } + if (isDisposed()) { + throw new IOException("Input closed"); //$NON-NLS-1$ + } + return command; } /* (non-Javadoc) @@ -277,8 +310,7 @@ public final class SWTConsole extends Composite throw new IOException(); } } catch (final InterruptedException e) { - LOGGER.log(Level.WARNING, - "Error in synchronization of prompting", e); //$NON-NLS-1$ + LOGGER.log(Level.WARNING, "Error in synchronization of prompting", e); //$NON-NLS-1$ command = null; Thread.currentThread().interrupt(); } finally { @@ -299,8 +331,7 @@ public final class SWTConsole extends Composite } /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String, long) - */ + * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String, long) */ @Override public String prompt(final String message, final long timeout) throws IOException { // TODO Auto-generated method stub @@ -340,10 +371,10 @@ public final class SWTConsole extends Composite } }); } - + @Override public void setPrompt(String prompt) { - setPrompt(new ConstantString(prompt)); + setPrompt(new ConstantString(prompt)); } /** @param string the text */ @@ -375,8 +406,7 @@ public final class SWTConsole extends Composite try { promptLock.wait(); } catch (final InterruptedException e) { - LOGGER.log(Level.SEVERE, - "Interruption while waiting prompt", e); //$NON-NLS-1$ + LOGGER.log(Level.SEVERE, "Interruption while waiting prompt", e); //$NON-NLS-1$ } } Display.getDefault().syncExec(new Runnable() { @@ -386,8 +416,7 @@ public final class SWTConsole extends Composite command = consoleInput.getText(); prompting = false; consoleInput.setText(EMPTY); - consoleOutput.append( - CMD_PREFIX + command + System.lineSeparator()); + consoleOutput.append(CMD_PREFIX + command + System.lineSeparator()); } }); promptLock.notifyAll();