/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package eric.JSprogram;



//package text;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;
public class LineNumber extends JComponent {
//    private final static Color DEFAULT_BACKGROUND = new Color(235, 230, 225);
    private final static Color DEFAULT_BACKGROUND = new Color(214, 221, 229);
    private final static Color DEFAULT_FOREGROUND = Color.black;
    private final static Font  DEFAULT_FONT = new Font("monospaced", Font.PLAIN, 12);
    //  LineNumber height (abends when I use MAX_VALUE)
    private final static int HEIGHT = Integer.MAX_VALUE - 1000000;
    //  Set right/left margin
    private final static int MARGIN = 5;
    //  Variables for this LineNumber component
    private FontMetrics fontMetrics;
    private int lineHeight;
    private int currentDigits;
    //  Metrics of the component used in the constructor
    private JComponent component;
    private int componentFontHeight;
    private int componentFontAscent;
    /**
     * Convenience constructor for Text Components
     */
    public LineNumber(JComponent component) {
        if (component == null) {
            setFont( DEFAULT_FONT );
            this.component = this;
        } else {
            setFont( component.getFont() );
            this.component = component;
        }
        setBackground( DEFAULT_BACKGROUND );
        setForeground( DEFAULT_FOREGROUND );
        setPreferredWidth( 99 );
    }
    /**
     *  Calculate the width needed to display the maximum line number
     */
    public void setPreferredWidth(int lines) {
        int digits = String.valueOf(lines).length();
        //  Update sizes when number of digits in the line number changes
        if (digits != currentDigits && digits > 1) {
            currentDigits = digits;
            int width = fontMetrics.charWidth( '0' ) * digits;
            Dimension d = getPreferredSize();
            d.setSize(2 * MARGIN + width, HEIGHT);
            setPreferredSize( d );
            setSize( d );
        }
    }
    /**
     *  Reset variables that are dependent on the font.
     */
    public void setFont(Font font) {
        super.setFont(font);
        fontMetrics = getFontMetrics( getFont() );
        componentFontHeight = fontMetrics.getHeight();
        componentFontAscent = fontMetrics.getAscent();
    }
    /**
     *  The line height defaults to the line height of the font for this
     *  component.
     */
    public int getLineHeight() {
        if (lineHeight == 0)
            return componentFontHeight;
        else
            return lineHeight;
    }
    /**
     *  Override the default line height with a positive value.
     *  For example, when you want line numbers for a JTable you could
     *  use the JTable row height.
     */
    public void setLineHeight(int lineHeight) {
        if (lineHeight > 0)
            this.lineHeight = lineHeight;
    }
    public int getStartOffset() {
        return component.getInsets().top + componentFontAscent;
    }
    public void paintComponent(Graphics g) {
        int lineHeight = getLineHeight();
        int startOffset = getStartOffset();
        Rectangle drawHere = g.getClipBounds();
        // Paint the background
        g.setColor( getBackground() );
        g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
        //  Determine the number of lines to draw in the foreground.
        g.setColor( getForeground() );
        int startLineNumber = (drawHere.y / lineHeight) + 1;
        int endLineNumber = startLineNumber + (drawHere.height / lineHeight);
        int start = (drawHere.y / lineHeight) * lineHeight + startOffset;
        for (int i = startLineNumber; i <= endLineNumber; i++) {
            String lineNumber = String.valueOf(i);
            int stringWidth = fontMetrics.stringWidth( lineNumber );
            int rowWidth = getSize().width;
            g.drawString(lineNumber, rowWidth - stringWidth - MARGIN, start);
            start += lineHeight;
        }
        int rows = component.getSize().height / componentFontHeight;
        setPreferredWidth( rows );
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame("LineNumberDemo");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        JPanel panel = new JPanel();
        frame.setContentPane( panel );
        panel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
        panel.setLayout(new BorderLayout());
        JTextArea textPane = new JTextArea();
        textPane.setFont( new Font("monospaced", Font.PLAIN, 12) );
        textPane.setText("abc");
        JScrollPane scrollPane = new JScrollPane(textPane);
        panel.add(scrollPane);
        scrollPane.setPreferredSize(new Dimension(300, 250));
        LineNumber lineNumber = new LineNumber( textPane );
        scrollPane.setRowHeaderView(lineNumber );
        frame.pack();
        frame.setVisible(true);
    }
}