class SwingTerminalImplementation extends GraphicalTerminalImplementation {

    private final JComponent component;
    private final SwingTerminalFontConfiguration fontConfiguration;

    /**
     * Creates a new {@code SwingTerminalImplementation}
     * @param component JComponent that is the Swing terminal surface
     * @param fontConfiguration Font configuration to use
     * @param initialTerminalSize Initial size of the terminal
     * @param deviceConfiguration Device configuration
     * @param colorConfiguration Color configuration
     * @param scrollController Controller to be used when inspecting scroll status
     */
    SwingTerminalImplementation(
            JComponent component,
            SwingTerminalFontConfiguration fontConfiguration,
            TerminalSize initialTerminalSize,
            TerminalEmulatorDeviceConfiguration deviceConfiguration,
            TerminalEmulatorColorConfiguration colorConfiguration,
            TerminalScrollController scrollController) {

        super(initialTerminalSize, deviceConfiguration, colorConfiguration, scrollController);
        this.component = component;
        this.fontConfiguration = fontConfiguration;

        //Prevent us from shrinking beyond one character
        component.setMinimumSize(new Dimension(fontConfiguration.getFontWidth(), fontConfiguration.getFontHeight()));

        component.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet());
        component.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet());

        //Make sure the component is double-buffered to prevent flickering
        component.setDoubleBuffered(true);

        component.addKeyListener(new TerminalInputListener());
        component.addMouseListener(new TerminalMouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                SwingTerminalImplementation.this.component.requestFocusInWindow();
            }
        });
        component.addHierarchyListener(e -> {
            if(e.getChangeFlags() == HierarchyEvent.DISPLAYABILITY_CHANGED) {
                if(e.getChanged().isDisplayable()) {
                    onCreated();
                }
                else {
                    onDestroyed();
                }
            }
        });
    }


    /**
     * Returns the current font configuration. Note that it is immutable and cannot be changed.
     * @return This SwingTerminal's current font configuration
     */
    public SwingTerminalFontConfiguration getFontConfiguration() {
        return fontConfiguration;
    }

    @Override
    protected int getFontHeight() {
        return fontConfiguration.getFontHeight();
    }

    @Override
    protected int getFontWidth() {
        return fontConfiguration.getFontWidth();
    }

    @Override
    protected int getHeight() {
        return component.getHeight();
    }

    @Override
    protected int getWidth() {
        return component.getWidth();
    }

    @Override
    protected Font getFontForCharacter(TextCharacter character) {
        return fontConfiguration.getFontForCharacter(character);
    }

    @Override
    protected boolean isTextAntiAliased() {
        return fontConfiguration.isAntiAliased();
    }

    @Override
    protected void repaint() {
        if(SwingUtilities.isEventDispatchThread()) {
            component.repaint();
        }
        else {
            SwingUtilities.invokeLater(component::repaint);
        }
    }

    @Override
    public com.googlecode.lanterna.input.KeyStroke readInput() {<FILL_FUNCTION_BODY>}
}

        if(SwingUtilities.isEventDispatchThread()) {
            throw new UnsupportedOperationException("Cannot call SwingTerminal.readInput() on the AWT thread");
        }
        return super.readInput();
    
<methods>public void addResizeListener(com.googlecode.lanterna.terminal.TerminalResizeListener) ,public void bell() ,public synchronized void clearScreen() ,public void close() ,public void disableSGR(com.googlecode.lanterna.SGR) ,public void enableSGR(com.googlecode.lanterna.SGR) ,public byte[] enquireTerminal(int, java.util.concurrent.TimeUnit) ,public synchronized void enterPrivateMode() ,public synchronized void exitPrivateMode() ,public synchronized void flush() ,public com.googlecode.lanterna.TerminalPosition getCursorPosition() ,public synchronized com.googlecode.lanterna.TerminalSize getTerminalSize() ,public com.googlecode.lanterna.graphics.TextGraphics newTextGraphics() ,public com.googlecode.lanterna.input.KeyStroke pollInput() ,public synchronized void putCharacter(char) ,public void putString(java.lang.String) ,public com.googlecode.lanterna.input.KeyStroke readInput() ,public void removeResizeListener(com.googlecode.lanterna.terminal.TerminalResizeListener) ,public void resetColorAndSGR() ,public void setBackgroundColor(com.googlecode.lanterna.TextColor) ,public synchronized void setCursorPosition(int, int) ,public synchronized void setCursorPosition(com.googlecode.lanterna.TerminalPosition) ,public void setCursorVisible(boolean) ,public void setForegroundColor(com.googlecode.lanterna.TextColor) <variables>private static final Set<java.lang.Character> TYPED_KEYS_TO_IGNORE,private java.awt.image.BufferedImage backbuffer,private boolean bellOn,private boolean blinkOn,private java.util.Timer blinkTimer,private final non-sealed com.googlecode.lanterna.terminal.swing.TerminalEmulatorColorConfiguration colorConfiguration,private java.awt.image.BufferedImage copybuffer,private boolean cursorIsVisible,private final non-sealed com.googlecode.lanterna.terminal.swing.TerminalEmulatorDeviceConfiguration deviceConfiguration,private final non-sealed com.googlecode.lanterna.terminal.swing.GraphicalTerminalImplementation.DirtyCellsLookupTable dirtyCellsLookupTable,private boolean enableInput,private final non-sealed java.lang.String enquiryString,private boolean hasBlinkingText,private final non-sealed BlockingQueue<com.googlecode.lanterna.input.KeyStroke> keyQueue,private int lastBufferUpdateScrollPosition,private int lastComponentHeight,private int lastComponentWidth,private com.googlecode.lanterna.TerminalPosition lastDrawnCursorPosition,private boolean needFullRedraw,private final non-sealed com.googlecode.lanterna.terminal.swing.TerminalScrollController scrollController,private final non-sealed com.googlecode.lanterna.terminal.virtual.DefaultVirtualTerminal virtualTerminal