2 * This file is part of lanterna (http://code.google.com/p/lanterna/).
4 * lanterna is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) 2010-2015 Martin
19 package com
.googlecode
.lanterna
.terminal
;
21 import com
.googlecode
.lanterna
.TerminalSize
;
22 import com
.googlecode
.lanterna
.terminal
.ansi
.CygwinTerminal
;
23 import com
.googlecode
.lanterna
.terminal
.ansi
.UnixTerminal
;
24 import com
.googlecode
.lanterna
.terminal
.swing
.*;
27 import java
.io
.IOException
;
28 import java
.io
.InputStream
;
29 import java
.io
.OutputStream
;
30 import java
.nio
.charset
.Charset
;
33 * This TerminalFactory implementation uses a simple auto-detection mechanism for figuring out which terminal
34 * implementation to create based on characteristics of the system the program is running on.
36 * Note that for all systems with a graphical environment present, the SwingTerminalFrame will be chosen. You can
37 * suppress this by calling setForceTextTerminal(true) on this factory.
40 public final class DefaultTerminalFactory
implements TerminalFactory
{
41 private static final OutputStream DEFAULT_OUTPUT_STREAM
= System
.out
;
42 private static final InputStream DEFAULT_INPUT_STREAM
= System
.in
;
43 private static final Charset DEFAULT_CHARSET
= Charset
.forName(System
.getProperty("file.encoding"));
45 private final OutputStream outputStream
;
46 private final InputStream inputStream
;
47 private final Charset charset
;
49 private TerminalSize initialTerminalSize
;
50 private boolean forceTextTerminal
;
51 private boolean forceAWTOverSwing
;
53 private boolean autoOpenTerminalFrame
;
54 private TerminalEmulatorAutoCloseTrigger autoCloseTrigger
;
55 private TerminalEmulatorColorConfiguration colorConfiguration
;
56 private TerminalEmulatorDeviceConfiguration deviceConfiguration
;
57 private AWTTerminalFontConfiguration fontConfiguration
;
58 private MouseCaptureMode mouseCaptureMode
;
61 * Creates a new DefaultTerminalFactory with all properties set to their defaults
63 public DefaultTerminalFactory() {
64 this(DEFAULT_OUTPUT_STREAM
, DEFAULT_INPUT_STREAM
, DEFAULT_CHARSET
);
68 * Creates a new DefaultTerminalFactory with I/O and character set options customisable.
69 * @param outputStream Output stream to use for text-based Terminal implementations
70 * @param inputStream Input stream to use for text-based Terminal implementations
71 * @param charset Character set to assume the client is using
73 @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
74 public DefaultTerminalFactory(OutputStream outputStream
, InputStream inputStream
, Charset charset
) {
75 this.outputStream
= outputStream
;
76 this.inputStream
= inputStream
;
77 this.charset
= charset
;
79 this.forceTextTerminal
= false;
80 this.autoOpenTerminalFrame
= true;
82 this.autoCloseTrigger
= TerminalEmulatorAutoCloseTrigger
.CloseOnExitPrivateMode
;
83 this.mouseCaptureMode
= null;
85 //SwingTerminal will replace these null values for the default implementation if they are unchanged
86 this.colorConfiguration
= null;
87 this.deviceConfiguration
= null;
88 this.fontConfiguration
= null;
92 public Terminal
createTerminal() throws IOException
{
93 if (GraphicsEnvironment
.isHeadless() || forceTextTerminal
|| System
.console() != null) {
94 if(isOperatingSystemWindows()) {
95 return createCygwinTerminal(outputStream
, inputStream
, charset
);
98 return createUnixTerminal(outputStream
, inputStream
, charset
);
102 return createTerminalEmulator();
107 * Creates a new terminal emulator window which will be either Swing-based or AWT-based depending on what is
108 * available on the system
109 * @return New terminal emulator exposed as a {@link Terminal} interface
111 public Terminal
createTerminalEmulator() {
113 if(!forceAWTOverSwing
&& hasSwing()) {
114 window
= createSwingTerminal();
117 window
= createAWTTerminal();
120 if(autoOpenTerminalFrame
) {
121 window
.setVisible(true);
123 return (Terminal
)window
;
126 public AWTTerminalFrame
createAWTTerminal() {
127 return new AWTTerminalFrame(
136 public SwingTerminalFrame
createSwingTerminal() {
137 return new SwingTerminalFrame(
141 fontConfiguration
instanceof SwingTerminalFontConfiguration ?
(SwingTerminalFontConfiguration
)fontConfiguration
: null,
146 private boolean hasSwing() {
148 Class
.forName("javax.swing.JComponent");
151 catch(Exception ignore
) {
157 * Sets a hint to the TerminalFactory of what size to use when creating the terminal. Most terminals are not created
158 * on request but for example the SwingTerminal and SwingTerminalFrame are and this value will be passed down on
160 * @param initialTerminalSize Size (in rows and columns) of the newly created terminal
161 * @return Reference to itself, so multiple .set-calls can be chained
163 public DefaultTerminalFactory
setInitialTerminalSize(TerminalSize initialTerminalSize
) {
164 this.initialTerminalSize
= initialTerminalSize
;
169 * Controls whether a SwingTerminalFrame shall always be created if the system is one with a graphical environment
170 * @param forceTextTerminal If true, will always create a text-based Terminal
171 * @return Reference to itself, so multiple .set-calls can be chained
173 public DefaultTerminalFactory
setForceTextTerminal(boolean forceTextTerminal
) {
174 this.forceTextTerminal
= forceTextTerminal
;
179 * Normally when a graphical terminal emulator is created by the factory, it will create a
180 * {@link SwingTerminalFrame} unless Swing is not present in the system. Setting this property to {@code true} will
181 * make it create an {@link AWTTerminalFrame} even if Swing is present
182 * @param forceAWTOverSwing If {@code true}, will always create an {@link AWTTerminalFrame} over a
183 * {@link SwingTerminalFrame} if asked to create a graphical terminal emulator
184 * @return Reference to itself, so multiple .set-calls can be chained
186 public DefaultTerminalFactory
setForceAWTOverSwing(boolean forceAWTOverSwing
) {
187 this.forceAWTOverSwing
= forceAWTOverSwing
;
192 * Controls whether a SwingTerminalFrame shall be automatically shown (.setVisible(true)) immediately after
193 * creation. If {@code false}, you will manually need to call {@code .setVisible(true)} on the JFrame to actually
194 * see the terminal window. Default for this value is {@code true}.
195 * @param autoOpenTerminalFrame Automatically open SwingTerminalFrame after creation
197 public void setAutoOpenTerminalEmulatorWindow(boolean autoOpenTerminalFrame
) {
198 this.autoOpenTerminalFrame
= autoOpenTerminalFrame
;
202 * Sets the title to use on created SwingTerminalFrames created by this factory
203 * @param title Title to use on created SwingTerminalFrames created by this factory
204 * @return Reference to itself, so multiple .set-calls can be chained
206 public DefaultTerminalFactory
setTerminalEmulatorTitle(String title
) {
212 * Sets the auto-close trigger to use on created SwingTerminalFrames created by this factory
213 * @param autoCloseTrigger Auto-close trigger to use on created SwingTerminalFrames created by this factory
214 * @return Reference to itself, so multiple .set-calls can be chained
216 public DefaultTerminalFactory
setTerminalEmulatorFrameAutoCloseTrigger(TerminalEmulatorAutoCloseTrigger autoCloseTrigger
) {
217 this.autoCloseTrigger
= autoCloseTrigger
;
222 * Sets the color configuration to use on created SwingTerminalFrames created by this factory
223 * @param colorConfiguration Color configuration to use on created SwingTerminalFrames created by this factory
224 * @return Reference to itself, so multiple .set-calls can be chained
226 public DefaultTerminalFactory
setTerminalEmulatorColorConfiguration(TerminalEmulatorColorConfiguration colorConfiguration
) {
227 this.colorConfiguration
= colorConfiguration
;
232 * Sets the device configuration to use on created SwingTerminalFrames created by this factory
233 * @param deviceConfiguration Device configuration to use on created SwingTerminalFrames created by this factory
234 * @return Reference to itself, so multiple .set-calls can be chained
236 public DefaultTerminalFactory
setTerminalEmulatorDeviceConfiguration(TerminalEmulatorDeviceConfiguration deviceConfiguration
) {
237 this.deviceConfiguration
= deviceConfiguration
;
242 * Sets the font configuration to use on created SwingTerminalFrames created by this factory
243 * @param fontConfiguration Font configuration to use on created SwingTerminalFrames created by this factory
244 * @return Reference to itself, so multiple .set-calls can be chained
246 public DefaultTerminalFactory
setTerminalEmulatorFontConfiguration(AWTTerminalFontConfiguration fontConfiguration
) {
247 this.fontConfiguration
= fontConfiguration
;
252 * Sets the mouse capture mode the terminal should use. Please note that this is an extension which isn't widely
254 * @param mouseCaptureMode Capture mode for mouse interactions
257 public DefaultTerminalFactory
setMouseCaptureMode(MouseCaptureMode mouseCaptureMode
) {
258 this.mouseCaptureMode
= mouseCaptureMode
;
262 private Terminal
createCygwinTerminal(OutputStream outputStream
, InputStream inputStream
, Charset charset
) throws IOException
{
263 return new CygwinTerminal(inputStream
, outputStream
, charset
);
266 private Terminal
createUnixTerminal(OutputStream outputStream
, InputStream inputStream
, Charset charset
) throws IOException
{
267 UnixTerminal unixTerminal
= new UnixTerminal(inputStream
, outputStream
, charset
);
268 if(mouseCaptureMode
!= null) {
269 unixTerminal
.setMouseCaptureMode(mouseCaptureMode
);
275 * Detects whether the running platform is Windows* by looking at the
276 * operating system name system property
278 private static boolean isOperatingSystemWindows() {
279 return System
.getProperty("os.name", "").toLowerCase().startsWith("windows");