debugger/swing_utils/src/main/com/thesett/aima/logic/fol/wam/debugger/swing/JTextGrid.java
protected void paintComponent(Graphics g)
    {
        Graphics2D graphics2D = (Graphics2D) g.create();
        Rectangle clipRect = (Rectangle) g.getClip();

        // Work out the area to be painted in grid coordinates against the clipping rectangle.
        int startCol = xToCol(clipRect.x);
        int startRow = yToRow(clipRect.y);
        int cols = xToCol(clipRect.x + clipRect.width);
        int rows = yToRow(clipRect.y + clipRect.height);

        graphics2D.setFont(getFont());
        graphics2D.setColor(getBackground());
        graphics2D.fillRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);

        initializeFontMetrics();

        if (useAntiAliasing)
        {
            graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        }

        SortedMap<Integer, Integer> hSeps = model.getHorizontalSeparators();
        int hSepOffset = 0;

        for (int row = 0; row <= rows; row++)
        {
            Integer hNextSep = null;

            if (!hSeps.isEmpty())
            {
                hNextSep = hSeps.firstKey();
            }

            if ((hNextSep != null) && (hNextSep == row))
            {
                hSepOffset += hSeps.get(hNextSep);
                hSeps.remove(hNextSep);
            }

            SortedMap<Integer, Integer> vSeps = model.getVerticalSeparators();
            int vSepOffset = 0;

            for (int col = 0; col <= cols; col++)
            {
                Integer vNextSep = null;

                if (!vSeps.isEmpty())
                {
                    vNextSep = vSeps.firstKey();
                }

                if ((vNextSep != null) && (vNextSep == col))
                {
                    int vSepWidth = vSeps.get(vNextSep);
                    vSepOffset += vSepWidth;
                    vSeps.remove(vNextSep);

                    // If adding a vertical separator row attributes should be rendered within it to fill the space
                    // left by the separator.
                    AttributeSet attributes = model.getRowAttribute(row);

                    Color bgColor = (attributes != null) ? (Color) attributes.get(AttributeSet.BACKGROUND_COLOR) : null;
                    bgColor = (bgColor == null) ? getBackground() : bgColor;

                    graphics2D.setColor(bgColor);
                    graphics2D.fillRect(colToX(col) + vSepOffset - vSepWidth, rowToY(row) + hSepOffset,
                        colToX(col) + vSepOffset, charHeight);
                }

                // Only render if within the clip rectangle
                if ((col >= startCol) && (row >= startRow))
                {
                    char character = model.getCharAt(col, row);

                    AttributeSet attributes = model.getAttributeAt(col, row);

                    Color bgColor = (attributes != null) ? (Color) attributes.get(AttributeSet.BACKGROUND_COLOR) : null;
                    bgColor = (bgColor == null) ? getBackground() : bgColor;

                    graphics2D.setColor(bgColor);
                    graphics2D.fillRect(colToX(col) + vSepOffset, rowToY(row) + hSepOffset, charWidth, charHeight);

                    graphics2D.setColor(getForeground());
                    graphics2D.drawString(Character.toString(character), colToX(col) + vSepOffset,
                        (rowToY((row + 1))) - descent + hSepOffset);
                }
            }
        }

        graphics2D.dispose();
    }
protected void paintComponent(Graphics g)
    {
        Graphics2D graphics2D = (Graphics2D) g.create();
        Rectangle clipRect = (Rectangle) g.getClip();

        // Work out the area to be painted in grid coordinates against the clipping rectangle.
        int startCol = xToCol(clipRect.x);
        int startRow = yToRow(clipRect.y);
        int cols = xToCol(clipRect.x + clipRect.width);
        int rows = yToRow(clipRect.y + clipRect.height);

        graphics2D.setFont(getFont());
        graphics2D.setColor(getBackground());
        graphics2D.fillRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);

        initializeFontMetrics();

        if (useAntiAliasing)
        {
            graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        }

        SortedMap<Integer, Integer> hSeps = model.getHorizontalSeparators();
        int hSepOffset = 0;

        for (int row = 0; row <= rows; row++)
        {
            Integer hNextSep = null;

            if (!hSeps.isEmpty())
            {
                hNextSep = hSeps.firstKey();
            }

            if ((hNextSep != null) && (hNextSep == row))
            {
                hSepOffset += hSeps.get(hNextSep);
                hSeps.remove(hNextSep);
            }

            SortedMap<Integer, Integer> vSeps = model.getVerticalSeparators();
            int vSepOffset = 0;

            for (int col = 0; col <= cols; col++)
            {
                Integer vNextSep = null;

                if (!vSeps.isEmpty())
                {
                    vNextSep = vSeps.firstKey();
                }

                if ((vNextSep != null) && (vNextSep == col))
                {
                    int vSepWidth = vSeps.get(vNextSep);
                    vSepOffset += vSepWidth;
                    vSeps.remove(vNextSep);

                    // If adding a vertical separator row attributes should be rendered within it to fill the space
                    // left by the separator.
                    AttributeSet attributes = model.getRowAttribute(row);

                    Color bgColor = (attributes != null) ? (Color) attributes.get(AttributeSet.BACKGROUND_COLOR) : null;
                    bgColor = (bgColor == null) ? getBackground() : bgColor;

                    graphics2D.setColor(bgColor);
                    graphics2D.fillRect(colToX(col) + vSepOffset - vSepWidth, rowToY(row) + hSepOffset,
                        colToX(col) + vSepOffset, charHeight);
                }

                // Only render if within the clip rectangle
                if ((col >= startCol) && (row >= startRow))
                {
                    char character = model.getCharAt(col, row);

                    AttributeSet attributes = model.getAttributeAt(col, row);

                    Color bgColor = (attributes != null) ? (Color) attributes.get(AttributeSet.BACKGROUND_COLOR) : null;
                    bgColor = (bgColor == null) ? getBackground() : bgColor;

                    graphics2D.setColor(bgColor);
                    graphics2D.fillRect(colToX(col) + vSepOffset, rowToY(row) + hSepOffset, charWidth, charHeight);

                    graphics2D.setColor(getForeground());
                    graphics2D.drawString(Character.toString(character), colToX(col) + vSepOffset,
                        (rowToY((row + 1))) - descent + hSepOffset);
                }
            }
        }

        graphics2D.dispose();
    }
{@inheritDoc}

<p/>Renders the text grid model.