class DefaultPanelRenderer implements ComponentRenderer<Panel> {
        private boolean fillAreaBeforeDrawingComponents = true;

        /**
         * If setting this to {@code false} (default is {@code true}), the {@link Panel} will not reset it's drawable
         * area with the space character ' ' before drawing all the components. Usually you <b>do</b> want to reset this
         * area before drawing but you might have a custom renderer that has prepared the area already and just want the
         * panel renderer to layout and draw the components in the panel without touching the existing content. One such
         * example is the {@code FullScreenTextGUITest}.
         * @param fillAreaBeforeDrawingComponents Should the panels area be cleared before drawing components?
         */
        public void setFillAreaBeforeDrawingComponents(boolean fillAreaBeforeDrawingComponents) {
            this.fillAreaBeforeDrawingComponents = fillAreaBeforeDrawingComponents;
        }

        @Override
        public TerminalSize getPreferredSize(Panel component) {
            synchronized(components) {
                cachedPreferredSize = layoutManager.getPreferredSize(components);
            }
            return cachedPreferredSize;
        }

        @Override
        public void drawComponent(TextGUIGraphics graphics, Panel panel) {
            if(isInvalid()) {
                layout(graphics.getSize());
            }

            if (fillAreaBeforeDrawingComponents) {
                // Reset the area
                graphics.applyThemeStyle(getThemeDefinition().getNormal());
                if (fillColorOverride != null) {
                    graphics.setBackgroundColor(fillColorOverride);
                }
                graphics.fill(' ');
            }

            synchronized(components) {
                for(Component child: components) {
                    if (!child.isVisible()) {
                        continue;
                    }
                    TextGUIGraphics componentGraphics = graphics.newTextGraphics(child.getPosition(), child.getSize());
                    child.draw(componentGraphics);
                }
            }
        }
    }

    @Override
    public TerminalSize calculatePreferredSize() {
        if(cachedPreferredSize != null && !isInvalid()) {
            return cachedPreferredSize;
        }
        return super.calculatePreferredSize();
    }

    @Override
    public boolean isInvalid() {
        synchronized(components) {
            for(Component component: components) {
                if(component.isVisible() && component.isInvalid()) {
                    return true;
                }
            }
        }
        return super.isInvalid() || layoutManager.hasChanged();
    }    

    @Override
    public Interactable nextFocus(Interactable fromThis) {<FILL_FUNCTION_BODY>

        boolean chooseNextAvailable = (fromThis == null);

        synchronized(components) {
            for(Component component : components) {
                if(!component.isVisible()) {
                    continue;
                }
                if(chooseNextAvailable) {
                    if(component instanceof Interactable && ((Interactable) component).isEnabled() && ((Interactable) component).isFocusable()) {
                        return (Interactable) component;
                    }
                    else if(component instanceof Container) {
                        Interactable firstInteractable = ((Container) (component)).nextFocus(null);
                        if(firstInteractable != null) {
                            return firstInteractable;
                        }
                    }
                    continue;
                }

                if(component == fromThis) {
                    chooseNextAvailable = true;
                    continue;
                }

                if(component instanceof Container) {
                    Container container = (Container) component;
                    if(fromThis.isInside(container)) {
                        Interactable next = container.nextFocus(fromThis);
                        if(next == null) {
                            chooseNextAvailable = true;
                        }
                        else {
                            return next;
                        }
                    }
                }
            }
            return null;
        }
    
<methods>public void <init>() ,public synchronized com.googlecode.lanterna.gui2.Panel addTo(com.googlecode.lanterna.gui2.Panel) ,public final synchronized void draw(com.googlecode.lanterna.gui2.TextGUIGraphics) ,public com.googlecode.lanterna.gui2.BasePane getBasePane() ,public com.googlecode.lanterna.TerminalPosition getGlobalPosition() ,public com.googlecode.lanterna.gui2.LayoutData getLayoutData() ,public com.googlecode.lanterna.gui2.Container getParent() ,public com.googlecode.lanterna.TerminalPosition getPosition() ,public final com.googlecode.lanterna.TerminalSize getPreferredSize() ,public synchronized ComponentRenderer<com.googlecode.lanterna.gui2.Panel> getRenderer() ,public com.googlecode.lanterna.TerminalSize getSize() ,public com.googlecode.lanterna.gui2.TextGUI getTextGUI() ,public synchronized com.googlecode.lanterna.graphics.Theme getTheme() ,public com.googlecode.lanterna.graphics.ThemeDefinition getThemeDefinition() ,public boolean hasParent(com.googlecode.lanterna.gui2.Container) ,public void invalidate() ,public boolean isInside(com.googlecode.lanterna.gui2.Container) ,public boolean isInvalid() ,public boolean isVisible() ,public synchronized void onAdded(com.googlecode.lanterna.gui2.Container) ,public synchronized void onRemoved(com.googlecode.lanterna.gui2.Container) ,public synchronized com.googlecode.lanterna.gui2.Panel setLayoutData(com.googlecode.lanterna.gui2.LayoutData) ,public synchronized com.googlecode.lanterna.gui2.Panel setPosition(com.googlecode.lanterna.TerminalPosition) ,public final synchronized com.googlecode.lanterna.gui2.Panel setPreferredSize(com.googlecode.lanterna.TerminalSize) ,public com.googlecode.lanterna.gui2.Panel setRenderer(ComponentRenderer<com.googlecode.lanterna.gui2.Panel>) ,public synchronized com.googlecode.lanterna.gui2.Panel setSize(com.googlecode.lanterna.TerminalSize) ,public synchronized com.googlecode.lanterna.gui2.Component setTheme(com.googlecode.lanterna.graphics.Theme) ,public com.googlecode.lanterna.gui2.Panel setVisible(boolean) ,public com.googlecode.lanterna.TerminalPosition toBasePane(com.googlecode.lanterna.TerminalPosition) ,public com.googlecode.lanterna.TerminalPosition toGlobal(com.googlecode.lanterna.TerminalPosition) ,public synchronized com.googlecode.lanterna.gui2.Border withBorder(com.googlecode.lanterna.gui2.Border) <variables>private ComponentRenderer<com.googlecode.lanterna.gui2.Panel> defaultRenderer,private com.googlecode.lanterna.TerminalSize explicitPreferredSize,private boolean invalid,private com.googlecode.lanterna.gui2.LayoutData layoutData,private ComponentRenderer<com.googlecode.lanterna.gui2.Panel> overrideRenderer,private com.googlecode.lanterna.gui2.Container parent,private com.googlecode.lanterna.TerminalPosition position,private com.googlecode.lanterna.TerminalSize size,private com.googlecode.lanterna.graphics.Theme themeOverride,private ComponentRenderer<com.googlecode.lanterna.gui2.Panel> themeRenderer,private com.googlecode.lanterna.graphics.Theme themeRenderersTheme,private boolean visible