9166e1c19bec44817a21297d87d949cb27b1a1f2
[fanfix.git] / MultiBackend.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2017 Kevin Lamonte
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29 package jexer.backend;
30
31 import java.util.LinkedList;
32 import java.util.List;
33
34 import jexer.event.TInputEvent;
35
36 /**
37 * MultiBackend mirrors its I/O to several backends.
38 */
39 public class MultiBackend implements Backend {
40
41 /**
42 * The screen to use.
43 */
44 private MultiScreen multiScreen;
45
46 /**
47 * The list of backends to use.
48 */
49 private List<Backend> backends = new LinkedList<Backend>();
50
51 /**
52 * Public constructor requires one backend. Note that this backend's
53 * screen will be replaced with a MultiScreen.
54 *
55 * @param backend the backend to add
56 */
57 public MultiBackend(final Backend backend) {
58 backends.add(backend);
59 if (backend instanceof TWindowBackend) {
60 multiScreen = new MultiScreen(((TWindowBackend) backend).getOtherScreen());
61 } else {
62 multiScreen = new MultiScreen(backend.getScreen());
63 }
64 }
65
66 /**
67 * Add a backend to the list.
68 *
69 * @param backend the backend to add
70 */
71 public void addBackend(final Backend backend) {
72 backends.add(backend);
73 if (backend instanceof TWindowBackend) {
74 multiScreen.addScreen(((TWindowBackend) backend).getOtherScreen());
75 } else {
76 multiScreen.addScreen(backend.getScreen());
77 }
78 }
79
80 /**
81 * Remove a backend from the list.
82 *
83 * @param backend the backend to remove
84 */
85 public void removeBackend(final Backend backend) {
86 if (backends.size() > 1) {
87 if (backend instanceof TWindowBackend) {
88 multiScreen.removeScreen(((TWindowBackend) backend).getOtherScreen());
89 } else {
90 multiScreen.removeScreen(backend.getScreen());
91 }
92 backends.remove(backend);
93 }
94 }
95
96 /**
97 * Getter for sessionInfo.
98 *
99 * @return the SessionInfo
100 */
101 public SessionInfo getSessionInfo() {
102 return backends.get(0).getSessionInfo();
103 }
104
105 /**
106 * Getter for screen.
107 *
108 * @return the Screen
109 */
110 public Screen getScreen() {
111 return multiScreen;
112 }
113
114 /**
115 * Subclasses must provide an implementation that syncs the logical
116 * screen to the physical device.
117 */
118 public void flushScreen() {
119 for (Backend backend: backends) {
120 backend.flushScreen();
121 }
122 }
123
124 /**
125 * Subclasses must provide an implementation to get keyboard, mouse, and
126 * screen resize events.
127 *
128 * @param queue list to append new events to
129 */
130 public void getEvents(List<TInputEvent> queue) {
131 for (Backend backend: backends) {
132 backend.getEvents(queue);
133 }
134 }
135
136 /**
137 * Subclasses must provide an implementation that closes sockets,
138 * restores console, etc.
139 */
140 public void shutdown() {
141 for (Backend backend: backends) {
142 backend.shutdown();
143 }
144 }
145
146 /**
147 * Subclasses must provide an implementation that sets the window title.
148 *
149 * @param title the new title
150 */
151 public void setTitle(final String title) {
152 for (Backend backend: backends) {
153 backend.setTitle(title);
154 }
155 }
156
157 /**
158 * Set listener to a different Object.
159 *
160 * @param listener the new listening object that run() wakes up on new
161 * input
162 */
163 public void setListener(final Object listener) {
164 for (Backend backend: backends) {
165 backend.setListener(listener);
166 }
167 }
168
169 }