package com.googlecode.lanterna.terminal.swing; import com.googlecode.lanterna.SGR; import com.googlecode.lanterna.TerminalSize; import com.googlecode.lanterna.TextColor; import com.googlecode.lanterna.graphics.TextGraphics; import com.googlecode.lanterna.input.*; import com.googlecode.lanterna.input.KeyStroke; import com.googlecode.lanterna.terminal.IOSafeTerminal; import com.googlecode.lanterna.terminal.ResizeListener; import javax.swing.*; import java.awt.*; import java.io.IOException; import java.util.concurrent.TimeUnit; /** * This class provides an Swing implementation of the {@link com.googlecode.lanterna.terminal.Terminal} interface that * is an embeddable component you can put into a Swing container. The class has static helper methods for opening a new * frame with a {@link SwingTerminal} as its content, similar to how the SwingTerminal used to work in earlier versions * of lanterna. This version supports private mode and non-private mode with a scrollback history. You can customize * many of the properties by supplying device configuration, font configuration and color configuration when you * construct the object. * @author martin */ public class SwingTerminal extends JComponent implements IOSafeTerminal { private final SwingTerminalImplementation terminalImplementation; /** * Creates a new SwingTerminal with all the defaults set and no scroll controller connected. */ public SwingTerminal() { this(new TerminalScrollController.Null()); } /** * Creates a new SwingTerminal with a particular scrolling controller that will be notified when the terminals * history size grows and will be called when this class needs to figure out the current scrolling position. * @param scrollController Controller for scrolling the terminal history */ @SuppressWarnings("WeakerAccess") public SwingTerminal(TerminalScrollController scrollController) { this(TerminalEmulatorDeviceConfiguration.getDefault(), SwingTerminalFontConfiguration.getDefault(), TerminalEmulatorColorConfiguration.getDefault(), scrollController); } /** * Creates a new SwingTerminal component using custom settings and no scroll controller. * @param deviceConfiguration Device configuration to use for this SwingTerminal * @param fontConfiguration Font configuration to use for this SwingTerminal * @param colorConfiguration Color configuration to use for this SwingTerminal */ public SwingTerminal( TerminalEmulatorDeviceConfiguration deviceConfiguration, SwingTerminalFontConfiguration fontConfiguration, TerminalEmulatorColorConfiguration colorConfiguration) { this(null, deviceConfiguration, fontConfiguration, colorConfiguration); } /** * Creates a new SwingTerminal component using custom settings and no scroll controller. * @param initialTerminalSize Initial size of the terminal, which will be used when calculating the preferred size * of the component. If null, it will default to 80x25. If the AWT layout manager forces * the component to a different size, the value of this parameter won't have any meaning * @param deviceConfiguration Device configuration to use for this SwingTerminal * @param fontConfiguration Font configuration to use for this SwingTerminal * @param colorConfiguration Color configuration to use for this SwingTerminal */ public SwingTerminal( TerminalSize initialTerminalSize, TerminalEmulatorDeviceConfiguration deviceConfiguration, SwingTerminalFontConfiguration fontConfiguration, TerminalEmulatorColorConfiguration colorConfiguration) { this(initialTerminalSize, deviceConfiguration, fontConfiguration, colorConfiguration, new TerminalScrollController.Null()); } /** * Creates a new SwingTerminal component using custom settings and a custom scroll controller. The scrolling * controller will be notified when the terminal's history size grows and will be called when this class needs to * figure out the current scrolling position. * @param deviceConfiguration Device configuration to use for this SwingTerminal * @param fontConfiguration Font configuration to use for this SwingTerminal * @param colorConfiguration Color configuration to use for this SwingTerminal * @param scrollController Controller to use for scrolling, the object passed in will be notified whenever the * scrollable area has changed */ public SwingTerminal( TerminalEmulatorDeviceConfiguration deviceConfiguration, SwingTerminalFontConfiguration fontConfiguration, TerminalEmulatorColorConfiguration colorConfiguration, TerminalScrollController scrollController) { this(null, deviceConfiguration, fontConfiguration, colorConfiguration, scrollController); } /** * Creates a new SwingTerminal component using custom settings and a custom scroll controller. The scrolling * controller will be notified when the terminal's history size grows and will be called when this class needs to * figure out the current scrolling position. * @param initialTerminalSize Initial size of the terminal, which will be used when calculating the preferred size * of the component. If null, it will default to 80x25. If the AWT layout manager forces * the component to a different size, the value of this parameter won't have any meaning * @param deviceConfiguration Device configuration to use for this SwingTerminal * @param fontConfiguration Font configuration to use for this SwingTerminal * @param colorConfiguration Color configuration to use for this SwingTerminal * @param scrollController Controller to use for scrolling, the object passed in will be notified whenever the * scrollable area has changed */ public SwingTerminal( TerminalSize initialTerminalSize, TerminalEmulatorDeviceConfiguration deviceConfiguration, SwingTerminalFontConfiguration fontConfiguration, TerminalEmulatorColorConfiguration colorConfiguration, TerminalScrollController scrollController) { //Enforce valid values on the input parameters if(deviceConfiguration == null) { deviceConfiguration = TerminalEmulatorDeviceConfiguration.getDefault(); } if(fontConfiguration == null) { fontConfiguration = SwingTerminalFontConfiguration.getDefault(); } if(colorConfiguration == null) { colorConfiguration = TerminalEmulatorColorConfiguration.getDefault(); } terminalImplementation = new SwingTerminalImplementation( this, fontConfiguration, initialTerminalSize, deviceConfiguration, colorConfiguration, scrollController); } /** * Overridden method from Swing's {@code JComponent} class that returns the preferred size of the terminal (in * pixels) * @return The terminal's preferred size in pixels */ @Override public synchronized Dimension getPreferredSize() { return terminalImplementation.getPreferredSize(); } /** * Overridden method from Swing's {@code JComponent} class that is called by OS window system when the component * needs to be redrawn * @param {@code Graphics} object to use when drawing the component */ @Override protected synchronized void paintComponent(Graphics componentGraphics) { terminalImplementation.paintComponent(componentGraphics); } //////////////////////////////////////////////////////////////////////////////// // Terminal methods below here, just forward to the implementation @Override public void enterPrivateMode() { terminalImplementation.enterPrivateMode(); } @Override public void exitPrivateMode() { terminalImplementation.exitPrivateMode(); } @Override public void clearScreen() { terminalImplementation.clearScreen(); } @Override public void setCursorPosition(int x, int y) { terminalImplementation.setCursorPosition(x, y); } @Override public void setCursorVisible(boolean visible) { terminalImplementation.setCursorVisible(visible); } @Override public void putCharacter(char c) { terminalImplementation.putCharacter(c); } @Override public void enableSGR(SGR sgr) { terminalImplementation.enableSGR(sgr); } @Override public void disableSGR(SGR sgr) { terminalImplementation.disableSGR(sgr); } @Override public void resetColorAndSGR() { terminalImplementation.resetColorAndSGR(); } @Override public void setForegroundColor(TextColor color) { terminalImplementation.setForegroundColor(color); } @Override public void setBackgroundColor(TextColor color) { terminalImplementation.setBackgroundColor(color); } @Override public TerminalSize getTerminalSize() { return terminalImplementation.getTerminalSize(); } @Override public byte[] enquireTerminal(int timeout, TimeUnit timeoutUnit) { return terminalImplementation.enquireTerminal(timeout, timeoutUnit); } @Override public void flush() { terminalImplementation.flush(); } @Override public KeyStroke pollInput() { return terminalImplementation.pollInput(); } @Override public KeyStroke readInput() throws IOException { return terminalImplementation.readInput(); } @Override public TextGraphics newTextGraphics() throws IOException { return terminalImplementation.newTextGraphics(); } @Override public void addResizeListener(ResizeListener listener) { terminalImplementation.addResizeListener(listener); } @Override public void removeResizeListener(ResizeListener listener) { terminalImplementation.removeResizeListener(listener); } }