All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.lanterna.gui2.Borders Maven / Gradle / Ivy

There is a newer version: 3.2.0-alpha1
Show newest version
/*
 * This file is part of lanterna (http://code.google.com/p/lanterna/).
 * 
 * lanterna is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 * 
 * Copyright (C) 2010-2020 Martin Berglund
 */
package com.googlecode.lanterna.gui2;

import com.googlecode.lanterna.*;
import com.googlecode.lanterna.graphics.TextGraphics;
import com.googlecode.lanterna.graphics.Theme;
import com.googlecode.lanterna.graphics.ThemeDefinition;

import java.util.Arrays;
import java.util.List;

/**
 * This class containers a couple of border implementation and utility methods for instantiating them. It also contains
 * a utility method for joining border line graphics together with adjacent lines so they blend in together:
 * {@code joinLinesWithFrame(..)}.
 * @author Martin
 */
public class Borders {
    private Borders() {
    }

    //Different ways to draw the border
    private enum BorderStyle {
        Solid,
        Bevel,
        ReverseBevel,
    }

    /**
     * Creates a {@code Border} that is drawn as a solid color single line surrounding the wrapped component
     * @return New solid color single line {@code Border}
     */
    public static Border singleLine() {
        return singleLine("");
    }

    /**
     * Creates a {@code Border} that is drawn as a solid color single line surrounding the wrapped component with a
     * title string normally drawn at the top-left side
     * @param title The title to draw on the border
     * @return New solid color single line {@code Border} with a title
     */
    public static Border singleLine(String title) {
        return new SingleLine(title, BorderStyle.Solid);
    }

    /**
     * Creates a {@code Border} that is drawn as a bevel color single line surrounding the wrapped component
     * @return New bevel color single line {@code Border}
     */
    public static Border singleLineBevel() {
        return singleLineBevel("");
    }

    /**
     * Creates a {@code Border} that is drawn as a bevel color single line surrounding the wrapped component with a
     * title string normally drawn at the top-left side
     * @param title The title to draw on the border
     * @return New bevel color single line {@code Border} with a title
     */
    public static Border singleLineBevel(String title) {
        return new SingleLine(title, BorderStyle.Bevel);
    }

    /**
     * Creates a {@code Border} that is drawn as a reverse bevel color single line surrounding the wrapped component
     * @return New reverse bevel color single line {@code Border}
     */
    public static Border singleLineReverseBevel() {
        return singleLineReverseBevel("");
    }

    /**
     * Creates a {@code Border} that is drawn as a reverse bevel color single line surrounding the wrapped component
     * with a title string normally drawn at the top-left side
     * @param title The title to draw on the border
     * @return New reverse bevel color single line {@code Border} with a title
     */
    public static Border singleLineReverseBevel(String title) {
        return new SingleLine(title, BorderStyle.ReverseBevel);
    }

    /**
     * Creates a {@code Border} that is drawn as a solid color double line surrounding the wrapped component
     * @return New solid color double line {@code Border}
     */
    public static Border doubleLine() {
        return doubleLine("");
    }

    /**
     * Creates a {@code Border} that is drawn as a solid color double line surrounding the wrapped component with a
     * title string normally drawn at the top-left side
     * @param title The title to draw on the border
     * @return New solid color double line {@code Border} with a title
     */
    public static Border doubleLine(String title) {
        return new DoubleLine(title, BorderStyle.Solid);
    }

    /**
     * Creates a {@code Border} that is drawn as a bevel color double line surrounding the wrapped component
     * @return New bevel color double line {@code Border}
     */
    public static Border doubleLineBevel() {
        return doubleLineBevel("");
    }

    /**
     * Creates a {@code Border} that is drawn as a bevel color double line surrounding the wrapped component with a
     * title string normally drawn at the top-left side
     * @param title The title to draw on the border
     * @return New bevel color double line {@code Border} with a title
     */
    public static Border doubleLineBevel(String title) {
        return new DoubleLine(title, BorderStyle.Bevel);
    }

    /**
     * Creates a {@code Border} that is drawn as a reverse bevel color double line surrounding the wrapped component
     * @return New reverse bevel color double line {@code Border}
     */
    public static Border doubleLineReverseBevel() {
        return doubleLineReverseBevel("");
    }

    /**
     * Creates a {@code Border} that is drawn as a reverse bevel color double line surrounding the wrapped component
     * with a title string normally drawn at the top-left side
     * @param title The title to draw on the border
     * @return New reverse bevel color double line {@code Border} with a title
     */
    public static Border doubleLineReverseBevel(String title) {
        return new DoubleLine(title, BorderStyle.ReverseBevel);
    }

    private static abstract class StandardBorder extends AbstractBorder {
        private final String title;
        protected final BorderStyle borderStyle;

        protected StandardBorder(String title, BorderStyle borderStyle) {
            if (title == null) {
                throw new IllegalArgumentException("Cannot create a border with null title");
            }
            this.borderStyle = borderStyle;
            this.title = title;
        }

        public String getTitle() {
            return title;
        }

        @Override
        public String toString() {
            return getClass().getSimpleName() + "{" + title + "}";
        }
    }

    private static abstract class AbstractBorderRenderer implements Border.BorderRenderer {
        private final BorderStyle borderStyle;

        protected AbstractBorderRenderer(BorderStyle borderStyle) {
            this.borderStyle = borderStyle;
        }

        @Override
        public TerminalSize getPreferredSize(Border component) {
            StandardBorder border = (StandardBorder)component;
            Component wrappedComponent = border.getComponent();
            TerminalSize preferredSize;
            if (wrappedComponent == null) {
                preferredSize = TerminalSize.ZERO;
            } else {
                preferredSize = wrappedComponent.getPreferredSize();
            }
            preferredSize = preferredSize.withRelativeColumns(2).withRelativeRows(2);
            String borderTitle = border.getTitle();
            return preferredSize.max(new TerminalSize((borderTitle.isEmpty() ? 2 : TerminalTextUtils.getColumnWidth(borderTitle) + 4), 2));
        }

        @Override
        public TerminalPosition getWrappedComponentTopLeftOffset() {
            return TerminalPosition.OFFSET_1x1;
        }

        @Override
        public TerminalSize getWrappedComponentSize(TerminalSize borderSize) {
            return borderSize
                    .withRelativeColumns(-Math.min(2, borderSize.getColumns()))
                    .withRelativeRows(-Math.min(2, borderSize.getRows()));
        }

        @Override
        public void drawComponent(TextGUIGraphics graphics, Border component) {
            StandardBorder border = (StandardBorder)component;
            Component wrappedComponent = border.getComponent();
            if(wrappedComponent == null) {
                return;
            }
            TerminalSize drawableArea = graphics.getSize();

            char horizontalLine = getHorizontalLine(component.getTheme());
            char verticalLine = getVerticalLine(component.getTheme());
            char bottomLeftCorner = getBottomLeftCorner(component.getTheme());
            char topLeftCorner = getTopLeftCorner(component.getTheme());
            char bottomRightCorner = getBottomRightCorner(component.getTheme());
            char topRightCorner = getTopRightCorner(component.getTheme());
            char titleLeft = getTitleLeft(component.getTheme());
            char titleRight = getTitleRight(component.getTheme());

            ThemeDefinition themeDefinition = component.getTheme().getDefinition(AbstractBorder.class);
            if(borderStyle == BorderStyle.Bevel) {
                graphics.applyThemeStyle(themeDefinition.getPreLight());
            }
            else {
                graphics.applyThemeStyle(themeDefinition.getNormal());
            }
            graphics.setCharacter(0, drawableArea.getRows() - 1, bottomLeftCorner);
            if(drawableArea.getRows() > 2) {
                graphics.drawLine(new TerminalPosition(0, drawableArea.getRows() - 2), new TerminalPosition(0, 1), verticalLine);
            }
            graphics.setCharacter(0, 0, topLeftCorner);
            if(drawableArea.getColumns() > 2) {
                graphics.drawLine(new TerminalPosition(1, 0), new TerminalPosition(drawableArea.getColumns() - 2, 0), horizontalLine);
            }

            if(borderStyle == BorderStyle.ReverseBevel) {
                graphics.applyThemeStyle(themeDefinition.getPreLight());
            }
            else {
                graphics.applyThemeStyle(themeDefinition.getNormal());
            }
            graphics.setCharacter(drawableArea.getColumns() - 1, 0, topRightCorner);
            if(drawableArea.getRows() > 2) {
                graphics.drawLine(new TerminalPosition(drawableArea.getColumns() - 1, 1),
                        new TerminalPosition(drawableArea.getColumns() - 1, drawableArea.getRows() - 2),
                        verticalLine);
            }
            graphics.setCharacter(drawableArea.getColumns() - 1, drawableArea.getRows() - 1, bottomRightCorner);
            if(drawableArea.getColumns() > 2) {
                graphics.drawLine(new TerminalPosition(1, drawableArea.getRows() - 1),
                        new TerminalPosition(drawableArea.getColumns() - 2, drawableArea.getRows() - 1),
                        horizontalLine);
            }


            if(border.getTitle() != null && !border.getTitle().isEmpty() &&
                    drawableArea.getColumns() >= TerminalTextUtils.getColumnWidth(border.getTitle()) + 4) {
                graphics.applyThemeStyle(themeDefinition.getActive());
                graphics.putString(2, 0, border.getTitle());

                if(borderStyle == BorderStyle.Bevel) {
                    graphics.applyThemeStyle(themeDefinition.getPreLight());
                }
                else {
                    graphics.applyThemeStyle(themeDefinition.getNormal());
                }
                graphics.setCharacter(1, 0, titleLeft);
                graphics.setCharacter(2 + TerminalTextUtils.getColumnWidth(border.getTitle()), 0, titleRight);
            }

            wrappedComponent.draw(graphics.newTextGraphics(getWrappedComponentTopLeftOffset(), getWrappedComponentSize(drawableArea)));


            joinLinesWithFrame(graphics);
        }

        protected abstract char getHorizontalLine(Theme theme);
        protected abstract char getVerticalLine(Theme theme);
        protected abstract char getBottomLeftCorner(Theme theme);
        protected abstract char getTopLeftCorner(Theme theme);
        protected abstract char getBottomRightCorner(Theme theme);
        protected abstract char getTopRightCorner(Theme theme);
        protected abstract char getTitleLeft(Theme theme);
        protected abstract char getTitleRight(Theme theme);
    }

    /**
     * This method will attempt to join line drawing characters with the outermost bottom and top rows and left and
     * right columns. For example, if a vertical left border character is ║ and the character immediately to the right
     * of it is ─, then the border character will be updated to ╟ to join the two together. Please note that this method
     * will only join the outer border columns and rows.
     * @param graphics Graphics to use when inspecting and joining characters
     */
    public static void joinLinesWithFrame(TextGraphics graphics) {
        TerminalSize drawableArea = graphics.getSize();
        if(drawableArea.getRows() <= 2 || drawableArea.getColumns() <= 2) {
            //Too small
            return;
        }

        int upperRow = 0;
        int lowerRow = drawableArea.getRows() - 1;
        int leftRow = 0;
        int rightRow = drawableArea.getColumns() - 1;

        List junctionFromBelowSingle = Arrays.asList(
                Symbols.SINGLE_LINE_VERTICAL,
                Symbols.BOLD_FROM_NORMAL_SINGLE_LINE_VERTICAL,
                Symbols.SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
                Symbols.SINGLE_LINE_BOTTOM_LEFT_CORNER,
                Symbols.SINGLE_LINE_BOTTOM_RIGHT_CORNER,
                Symbols.SINGLE_LINE_T_LEFT,
                Symbols.SINGLE_LINE_T_RIGHT,
                Symbols.SINGLE_LINE_T_UP,
                Symbols.SINGLE_LINE_T_DOUBLE_LEFT,
                Symbols.SINGLE_LINE_T_DOUBLE_RIGHT,
                Symbols.DOUBLE_LINE_T_SINGLE_UP);
        List junctionFromBelowDouble = Arrays.asList(
                Symbols.DOUBLE_LINE_VERTICAL,
                Symbols.DOUBLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_BOTTOM_LEFT_CORNER,
                Symbols.DOUBLE_LINE_BOTTOM_RIGHT_CORNER,
                Symbols.DOUBLE_LINE_T_LEFT,
                Symbols.DOUBLE_LINE_T_RIGHT,
                Symbols.DOUBLE_LINE_T_UP,
                Symbols.DOUBLE_LINE_T_SINGLE_LEFT,
                Symbols.DOUBLE_LINE_T_SINGLE_RIGHT,
                Symbols.SINGLE_LINE_T_DOUBLE_UP);
        List junctionFromAboveSingle = Arrays.asList(
                Symbols.SINGLE_LINE_VERTICAL,
                Symbols.BOLD_TO_NORMAL_SINGLE_LINE_VERTICAL,
                Symbols.SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
                Symbols.SINGLE_LINE_TOP_LEFT_CORNER,
                Symbols.SINGLE_LINE_TOP_RIGHT_CORNER,
                Symbols.SINGLE_LINE_T_LEFT,
                Symbols.SINGLE_LINE_T_RIGHT,
                Symbols.SINGLE_LINE_T_DOWN,
                Symbols.SINGLE_LINE_T_DOUBLE_LEFT,
                Symbols.SINGLE_LINE_T_DOUBLE_RIGHT,
                Symbols.DOUBLE_LINE_T_SINGLE_DOWN);
        List junctionFromAboveDouble = Arrays.asList(
                Symbols.DOUBLE_LINE_VERTICAL,
                Symbols.DOUBLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_TOP_LEFT_CORNER,
                Symbols.DOUBLE_LINE_TOP_RIGHT_CORNER,
                Symbols.DOUBLE_LINE_T_LEFT,
                Symbols.DOUBLE_LINE_T_RIGHT,
                Symbols.DOUBLE_LINE_T_DOWN,
                Symbols.DOUBLE_LINE_T_SINGLE_LEFT,
                Symbols.DOUBLE_LINE_T_SINGLE_RIGHT,
                Symbols.SINGLE_LINE_T_DOUBLE_DOWN);
        List junctionFromLeftSingle = Arrays.asList(
                Symbols.SINGLE_LINE_HORIZONTAL,
                Symbols.BOLD_TO_NORMAL_SINGLE_LINE_HORIZONTAL,
                Symbols.SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
                Symbols.SINGLE_LINE_BOTTOM_LEFT_CORNER,
                Symbols.SINGLE_LINE_TOP_LEFT_CORNER,
                Symbols.SINGLE_LINE_T_UP,
                Symbols.SINGLE_LINE_T_DOWN,
                Symbols.SINGLE_LINE_T_RIGHT,
                Symbols.SINGLE_LINE_T_DOUBLE_UP,
                Symbols.SINGLE_LINE_T_DOUBLE_DOWN,
                Symbols.DOUBLE_LINE_T_SINGLE_RIGHT);
        List junctionFromLeftDouble = Arrays.asList(
                Symbols.DOUBLE_LINE_HORIZONTAL,
                Symbols.DOUBLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_BOTTOM_LEFT_CORNER,
                Symbols.DOUBLE_LINE_TOP_LEFT_CORNER,
                Symbols.DOUBLE_LINE_T_UP,
                Symbols.DOUBLE_LINE_T_DOWN,
                Symbols.DOUBLE_LINE_T_RIGHT,
                Symbols.DOUBLE_LINE_T_SINGLE_UP,
                Symbols.DOUBLE_LINE_T_SINGLE_DOWN,
                Symbols.SINGLE_LINE_T_DOUBLE_RIGHT);
        List junctionFromRightSingle = Arrays.asList(
                Symbols.SINGLE_LINE_HORIZONTAL,
                Symbols.BOLD_FROM_NORMAL_SINGLE_LINE_HORIZONTAL,
                Symbols.SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
                Symbols.SINGLE_LINE_BOTTOM_RIGHT_CORNER,
                Symbols.SINGLE_LINE_TOP_RIGHT_CORNER,
                Symbols.SINGLE_LINE_T_UP,
                Symbols.SINGLE_LINE_T_DOWN,
                Symbols.SINGLE_LINE_T_LEFT,
                Symbols.SINGLE_LINE_T_DOUBLE_UP,
                Symbols.SINGLE_LINE_T_DOUBLE_DOWN,
                Symbols.DOUBLE_LINE_T_SINGLE_LEFT);
        List junctionFromRightDouble = Arrays.asList(
                Symbols.DOUBLE_LINE_HORIZONTAL,
                Symbols.DOUBLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
                Symbols.DOUBLE_LINE_BOTTOM_RIGHT_CORNER,
                Symbols.DOUBLE_LINE_TOP_RIGHT_CORNER,
                Symbols.DOUBLE_LINE_T_UP,
                Symbols.DOUBLE_LINE_T_DOWN,
                Symbols.DOUBLE_LINE_T_LEFT,
                Symbols.DOUBLE_LINE_T_SINGLE_UP,
                Symbols.DOUBLE_LINE_T_SINGLE_DOWN,
                Symbols.SINGLE_LINE_T_DOUBLE_LEFT);

        //Go horizontally and check vertical neighbours if it's possible to extend lines into the border
        for(int column = 1; column < drawableArea.getColumns() - 1; column++) {
            //Check first row
            TextCharacter borderCharacter = graphics.getCharacter(column, upperRow);
            if(borderCharacter == null) {
                continue;
            }
            TextCharacter neighbourCharacter = graphics.getCharacter(column, upperRow + 1);
            if(neighbourCharacter != null) {
                char neighbour = neighbourCharacter.getCharacter();
                if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_HORIZONTAL) {
                    if(junctionFromBelowSingle.contains(neighbour)) {
                        graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOWN));
                    }
                    else if(junctionFromBelowDouble.contains(neighbour)) {
                        graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_DOWN));
                    }
                }
                else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_HORIZONTAL) {
                    if(junctionFromBelowSingle.contains(neighbour)) {
                        graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_DOWN));
                    }
                    else if(junctionFromBelowDouble.contains(neighbour)) {
                        graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_DOWN));
                    }
                }
            }

            //Check last row
            borderCharacter = graphics.getCharacter(column, lowerRow);
            if(borderCharacter == null) {
                continue;
            }
            neighbourCharacter = graphics.getCharacter(column, lowerRow - 1);
            if(neighbourCharacter != null) {
                char neighbour = neighbourCharacter.getCharacter();
                if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_HORIZONTAL) {
                    if(junctionFromAboveSingle.contains(neighbour)) {
                        graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_UP));
                    }
                    else if(junctionFromAboveDouble.contains(neighbour)) {
                        graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_UP));
                    }
                }
                else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_HORIZONTAL) {
                    if(junctionFromAboveSingle.contains(neighbour)) {
                        graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_UP));
                    }
                    else if(junctionFromAboveDouble.contains(neighbour)) {
                        graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_UP));
                    }
                }
            }
        }

        //Go vertically and check horizontal neighbours if it's possible to extend lines into the border
        for(int row = 1; row < drawableArea.getRows() - 1; row++) {
            //Check first column
            TextCharacter borderCharacter = graphics.getCharacter(leftRow, row);
            if(borderCharacter == null) {
                continue;
            }
            TextCharacter neighbourCharacter = graphics.getCharacter(leftRow + 1, row);
            if(neighbourCharacter != null) {
                char neighbour = neighbourCharacter.getCharacter();
                if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_VERTICAL) {
                    if(junctionFromRightSingle.contains(neighbour)) {
                        graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_RIGHT));
                    }
                    else if(junctionFromRightDouble.contains(neighbour)) {
                        graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_RIGHT));
                    }
                }
                else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_VERTICAL) {
                    if(junctionFromRightSingle.contains(neighbour)) {
                        graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_RIGHT));
                    }
                    else if(junctionFromRightDouble.contains(neighbour)) {
                        graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_RIGHT));
                    }
                }
            }

            //Check last column
            borderCharacter = graphics.getCharacter(rightRow, row);
            if(borderCharacter == null) {
                continue;
            }
            neighbourCharacter = graphics.getCharacter(rightRow - 1, row);
            if(neighbourCharacter != null) {
                char neighbour = neighbourCharacter.getCharacter();
                if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_VERTICAL) {
                    if(junctionFromLeftSingle.contains(neighbour)) {
                        graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_LEFT));
                    }
                    else if(junctionFromLeftDouble.contains(neighbour)) {
                        graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_LEFT));
                    }
                }
                else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_VERTICAL) {
                    if(junctionFromLeftSingle.contains(neighbour)) {
                        graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_LEFT));
                    }
                    else if(junctionFromLeftDouble.contains(neighbour)) {
                        graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_LEFT));
                    }
                }
            }
        }
    }

    private static class SingleLine extends StandardBorder {
        private SingleLine(String title, BorderStyle borderStyle) {
            super(title, borderStyle);
        }

        @Override
        protected BorderRenderer createDefaultRenderer() {
            return new SingleLineRenderer(borderStyle);
        }
    }

    private static class SingleLineRenderer extends AbstractBorderRenderer {
        public SingleLineRenderer(BorderStyle borderStyle) {
            super(borderStyle);
        }

        @Override
        protected char getTopRightCorner(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("TOP_RIGHT_CORNER", Symbols.SINGLE_LINE_TOP_RIGHT_CORNER);
        }

        @Override
        protected char getBottomRightCorner(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("BOTTOM_RIGHT_CORNER", Symbols.SINGLE_LINE_BOTTOM_RIGHT_CORNER);
        }

        @Override
        protected char getTopLeftCorner(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("TOP_LEFT_CORNER", Symbols.SINGLE_LINE_TOP_LEFT_CORNER);
        }

        @Override
        protected char getBottomLeftCorner(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("BOTTOM_LEFT_CORNER", Symbols.SINGLE_LINE_BOTTOM_LEFT_CORNER);
        }

        @Override
        protected char getVerticalLine(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("VERTICAL_LINE", Symbols.SINGLE_LINE_VERTICAL);
        }

        @Override
        protected char getHorizontalLine(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("HORIZONTAL_LINE", Symbols.SINGLE_LINE_HORIZONTAL);
        }

        @Override
        protected char getTitleLeft(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("TITLE_LEFT", Symbols.SINGLE_LINE_HORIZONTAL);
        }

        @Override
        protected char getTitleRight(Theme theme) {
            return theme.getDefinition(SingleLine.class).getCharacter("TITLE_RIGHT", Symbols.SINGLE_LINE_HORIZONTAL);
        }
    }

    private static class DoubleLine extends StandardBorder {
        private DoubleLine(String title, BorderStyle borderStyle) {
            super(title, borderStyle);
        }

        @Override
        protected BorderRenderer createDefaultRenderer() {
            return new DoubleLineRenderer(borderStyle);
        }
    }

    private static class DoubleLineRenderer extends AbstractBorderRenderer {
        public DoubleLineRenderer(BorderStyle borderStyle) {
            super(borderStyle);
        }

        @Override
        protected char getTopRightCorner(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("TOP_RIGHT_CORNER", Symbols.DOUBLE_LINE_TOP_RIGHT_CORNER);
        }

        @Override
        protected char getBottomRightCorner(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("BOTTOM_RIGHT_CORNER", Symbols.DOUBLE_LINE_BOTTOM_RIGHT_CORNER);
        }

        @Override
        protected char getTopLeftCorner(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("TOP_LEFT_CORNER", Symbols.DOUBLE_LINE_TOP_LEFT_CORNER);
        }

        @Override
        protected char getBottomLeftCorner(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("BOTTOM_LEFT_CORNER", Symbols.DOUBLE_LINE_BOTTOM_LEFT_CORNER);
        }

        @Override
        protected char getVerticalLine(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("VERTICAL_LINE", Symbols.DOUBLE_LINE_VERTICAL);
        }

        @Override
        protected char getHorizontalLine(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("HORIZONTAL_LINE", Symbols.DOUBLE_LINE_HORIZONTAL);
        }

        @Override
        protected char getTitleLeft(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("TITLE_LEFT", Symbols.DOUBLE_LINE_HORIZONTAL);
        }

        @Override
        protected char getTitleRight(Theme theme) {
            return theme.getDefinition(DoubleLine.class).getCharacter("TITLE_RIGHT", Symbols.DOUBLE_LINE_HORIZONTAL);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy