+++ /dev/null
-/*
- * This file is part of lanterna (http://code.google.com/p/lanterna/).
- *
- * lanterna is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright (C) 2010-2015 Martin
- */
-package com.googlecode.lanterna.gui2;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Default implementation of TextGUIThread, this class runs the GUI event processing on a dedicated thread. The GUI
- * needs to be explicitly started in order for the event processing loop to begin, so you must call {@code start()}
- * for this. The GUI thread will stop if {@code stop()} is called, the input stream returns EOF or an exception is
- * thrown from inside the event handling loop.
- * <p>
- * Here is an example of how to use this {@code TextGUIThread}:
- * <pre>
- * {@code
- * MultiWindowTextGUI textGUI = new MultiWindowTextGUI(new SeparateTextGUIThread.Factory(), screen);
- * // ... add components ...
- * ((AsynchronousTextGUIThread)textGUI.getGUIThread()).start();
- * // ... this thread will continue while the GUI runs on a separate thread ...
- * }
- * </pre>
- * @see TextGUIThread
- * @see SameTextGUIThread
- * @author Martin
- */
-public class SeparateTextGUIThread extends AbstractTextGUIThread implements AsynchronousTextGUIThread {
- private volatile State state;
- private final Thread textGUIThread;
- private final CountDownLatch waitLatch;
-
- private SeparateTextGUIThread(TextGUI textGUI) {
- super(textGUI);
- this.waitLatch = new CountDownLatch(1);
- this.textGUIThread = new Thread("LanternaGUI") {
- @Override
- public void run() {
- mainGUILoop();
- }
- };
- state = State.CREATED;
- }
-
- @Override
- public void start() {
- textGUIThread.start();
- state = State.STARTED;
- }
-
- @Override
- public void stop() {
- if(state != State.STARTED) {
- return;
- }
-
- state = State.STOPPING;
- }
-
- @Override
- public void waitForStop() throws InterruptedException {
- waitLatch.await();
- }
-
- @Override
- public State getState() {
- return state;
- }
-
- @Override
- public Thread getThread() {
- return textGUIThread;
- }
-
- @Override
- public void invokeLater(Runnable runnable) throws IllegalStateException {
- if(state != State.STARTED) {
- throw new IllegalStateException("Cannot schedule " + runnable + " for execution on the TextGUIThread " +
- "because the thread is in " + state + " state");
- }
- super.invokeLater(runnable);
- }
-
- private void mainGUILoop() {
- try {
- //Draw initial screen, after this only draw when the GUI is marked as invalid
- try {
- textGUI.updateScreen();
- }
- catch(IOException e) {
- exceptionHandler.onIOException(e);
- }
- catch(RuntimeException e) {
- exceptionHandler.onRuntimeException(e);
- }
- while(state == State.STARTED) {
- try {
- if (!processEventsAndUpdate()) {
- try {
- Thread.sleep(1);
- }
- catch(InterruptedException ignored) {}
- }
- }
- catch(EOFException e) {
- stop();
- break; //Break out quickly from the main loop
- }
- catch(IOException e) {
- if(exceptionHandler.onIOException(e)) {
- stop();
- break;
- }
- }
- catch(RuntimeException e) {
- if(exceptionHandler.onRuntimeException(e)) {
- stop();
- break;
- }
- }
- }
- }
- finally {
- state = State.STOPPED;
- waitLatch.countDown();
- }
- }
-
-
- /**
- * Factory class for creating SeparateTextGUIThread objects
- */
- public static class Factory implements TextGUIThreadFactory {
- @Override
- public TextGUIThread createTextGUIThread(TextGUI textGUI) {
- return new SeparateTextGUIThread(textGUI);
- }
- }
-}