import java.util.Collections;
import java.util.HashMap;
import java.util.List;
-import java.util.LinkedList;
import jexer.TImage;
import jexer.bits.Cell;
reloadOptions();
// Spin up the input reader
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
readerThread = new Thread(this);
readerThread.start();
reloadOptions();
// Spin up the input reader
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
readerThread = new Thread(this);
readerThread.start();
// available() will often return > 1, so we need to read in chunks to
// stay caught up.
char [] readBuffer = new char[128];
- List<TInputEvent> events = new LinkedList<TInputEvent>();
+ List<TInputEvent> events = new ArrayList<TInputEvent>();
while (!done && !stopReaderThread) {
try {
*/
protected TerminalReader terminal;
+ /**
+ * By default, GenericBackend adds a cmAbort after it sees
+ * cmBackendDisconnect, so that TApplication will exit when the user
+ * closes the Swing window or disconnects the ECMA48 streams. But
+ * MultiBackend wraps multiple Backends, and needs to decide when to send
+ * cmAbort differently. Setting this to false is how it manages that.
+ * Note package private access.
+ */
+ boolean abortOnDisconnect = true;
+
// ------------------------------------------------------------------------
// Constructors -----------------------------------------------------------
// ------------------------------------------------------------------------
// This default backend assumes a single user, and if that user
// becomes disconnected we should terminate the application.
- if (queue.size() > 0) {
+ if ((queue.size() > 0) && (abortOnDisconnect == true)) {
TInputEvent event = queue.get(queue.size() - 1);
if (event instanceof TCommandEvent) {
TCommandEvent command = (TCommandEvent) event;
*/
package jexer.backend;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.List;
+import jexer.event.TCommandEvent;
import jexer.event.TInputEvent;
+import static jexer.TCommand.*;
/**
* MultiBackend mirrors its I/O to several backends.
/**
* The list of backends to use.
*/
- private List<Backend> backends = new LinkedList<Backend>();
+ private List<Backend> backends = new ArrayList<Backend>();
+
+ /**
+ * The SessionInfo to return.
+ */
+ private SessionInfo sessionInfo;
// ------------------------------------------------------------------------
// Constructors -----------------------------------------------------------
} else {
multiScreen = new MultiScreen(backend.getScreen());
}
+ if (backend instanceof GenericBackend) {
+ ((GenericBackend) backend).abortOnDisconnect = false;
+ }
+ sessionInfo = backend.getSessionInfo();
}
// ------------------------------------------------------------------------
* @return the SessionInfo
*/
public SessionInfo getSessionInfo() {
- return backends.get(0).getSessionInfo();
+ return sessionInfo;
}
/**
* @return if true, getEvents() has something to return to the application
*/
public boolean hasEvents() {
+ if (backends.size() == 0) {
+ return true;
+ }
for (Backend backend: backends) {
if (backend.hasEvents()) {
return true;
* @param queue list to append new events to
*/
public void getEvents(List<TInputEvent> queue) {
+ List<Backend> backendsToRemove = null;
for (Backend backend: backends) {
- backend.getEvents(queue);
+ if (backend.hasEvents()) {
+ backend.getEvents(queue);
+
+ // This default backend assumes a single user, and if that
+ // user becomes disconnected we should terminate the
+ // application.
+ if (queue.size() > 0) {
+ TInputEvent event = queue.get(queue.size() - 1);
+ if (event instanceof TCommandEvent) {
+ TCommandEvent command = (TCommandEvent) event;
+ if (command.equals(cmBackendDisconnect)) {
+ if (backendsToRemove == null) {
+ backendsToRemove = new ArrayList<Backend>();
+ }
+ backendsToRemove.add(backend);
+ }
+ }
+ }
+ }
+ }
+ if (backendsToRemove != null) {
+ for (Backend backend: backendsToRemove) {
+ multiScreen.removeScreen(backend.getScreen());
+ backends.remove(backend);
+ backend.shutdown();
+ }
+ }
+ if (backends.size() == 0) {
+ queue.add(new TCommandEvent(cmAbort));
}
}
} else {
multiScreen.addScreen(backend.getScreen());
}
+ if (backend instanceof GenericBackend) {
+ ((GenericBackend) backend).abortOnDisconnect = false;
+ }
}
/**
*/
package jexer.backend;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.List;
import jexer.bits.Cell;
/**
* The list of screens to use.
*/
- private List<Screen> screens = new LinkedList<Screen>();
+ private List<Screen> screens = new ArrayList<Screen>();
// ------------------------------------------------------------------------
// Constructors -----------------------------------------------------------
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.JComponent;
mouse1 = false;
mouse2 = false;
mouse3 = false;
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
// Add listeners to Swing.
swing.addKeyListener(this);
mouse1 = false;
mouse2 = false;
mouse3 = false;
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
// Add listeners to Swing.
swing.addKeyListener(this);
* @param event window event received
*/
public void windowClosing(final WindowEvent event) {
- // Drop a cmAbort and walk away
+ // Drop a cmBackendDisconnect and walk away
synchronized (eventQueue) {
- eventQueue.add(new TCommandEvent(cmAbort));
+ eventQueue.add(new TCommandEvent(cmBackendDisconnect));
resetBlinkTimer();
}
if (listener != null) {
*/
package jexer.backend;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.List;
+import jexer.TApplication;
+import jexer.TWindow;
+import jexer.event.TCommandEvent;
import jexer.event.TInputEvent;
import jexer.event.TKeypressEvent;
import jexer.event.TMouseEvent;
import jexer.event.TResizeEvent;
-import jexer.TApplication;
-import jexer.TWindow;
+import static jexer.TCommand.*;
/**
* TWindowBackend uses a window in one TApplication to provide a backend for
super(application, title, width, height);
this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
sessionInfo = new TSessionInfo(width, height);
otherScreen = new OtherScreen(this);
otherScreen.setDimensions(width - 2, height - 2);
super(application, title, width, height, flags);
this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
sessionInfo = new TSessionInfo(width, height);
otherScreen = new OtherScreen(this);
otherScreen.setDimensions(width - 2, height - 2);
super(application, title, x, y, width, height);
this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
sessionInfo = new TSessionInfo(width, height);
otherScreen = new OtherScreen(this);
otherScreen.setDimensions(width - 2, height - 2);
super(application, title, x, y, width, height, flags);
this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
+ eventQueue = new ArrayList<TInputEvent>();
sessionInfo = new TSessionInfo(width, height);
otherScreen = new OtherScreen(this);
otherScreen.setDimensions(width - 2, height - 2);
*/
@Override
public void onClose() {
- // TODO: send a screen disconnect
+ synchronized (eventQueue) {
+ eventQueue.add(new TCommandEvent(cmBackendDisconnect));
+ }
}
// ------------------------------------------------------------------------