FancyCaret.java Source code

Java tutorial

Introduction

Here is the source code for FancyCaret.java

Source

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.JTextComponent;

public class FancyCaret extends DefaultCaret {

    protected synchronized void damage(Rectangle r) {
        if (r == null)
            return;

        x = r.x;
        y = r.y;
        height = r.height;
        if (width <= 0)
            width = getComponent().getWidth();

        repaint();
    }

    public void paint(Graphics g) {
        JTextComponent comp = getComponent();
        if (comp == null)
            return;

        int dot = getDot();
        Rectangle r = null;
        char dotChar;
        try {
            r = comp.modelToView(dot);
            if (r == null)
                return;
            dotChar = comp.getText(dot, 1).charAt(0);
        } catch (BadLocationException e) {
            return;
        }

        if ((x != r.x) || (y != r.y)) {
            repaint();
            x = r.x;
            y = r.y;
            height = r.height;
        }

        g.setColor(comp.getCaretColor());
        g.setXORMode(comp.getBackground());

        if (dotChar == '\n') {
            int diam = r.height;
            if (isVisible())
                g.fillArc(r.x - diam / 2, r.y, diam, diam, 270, 180); // half circle
            width = diam / 2 + 2;
            return;
        }

        if (dotChar == '\t')
            try {
                Rectangle nextr = comp.modelToView(dot + 1);
                if ((r.y == nextr.y) && (r.x < nextr.x)) {
                    width = nextr.x - r.x;
                    if (isVisible())
                        g.fillRoundRect(r.x, r.y, width, r.height, 12, 12);
                    return;
                } else
                    dotChar = ' ';
            } catch (BadLocationException e) {
                dotChar = ' ';
            }

        width = g.getFontMetrics().charWidth(dotChar);
        if (isVisible())
            g.fillRect(r.x, r.y, width, r.height);
    }

    public static void main(String args[]) {
        JFrame frame = new JFrame("FancyCaret demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTextArea area = new JTextArea(8, 32);
        area.setCaret(new FancyCaret());
        area.setText("VI\tVirgin Islands \nVA      Virginia\nVT\tVermont");
        frame.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
}