001: /*
002: This library is free software; you can redistribute it and/or
003: modify it under the terms of the GNU General Public
004: License as published by the Free Software Foundation; either
005: version 2 of the license, or (at your option) any later version.
006: */
007:
008: package org.gjt.jclasslib.browser.detail.attributes.code;
009:
010: import javax.swing.*;
011: import java.awt.*;
012: import java.awt.font.*;
013: import java.text.AttributedCharacterIterator;
014: import java.text.AttributedString;
015: import java.util.HashMap;
016: import java.util.Map;
017:
018: /**
019: Line number renderer used as a row header view for a <tt>BytecodeDisplay</tt>.
020:
021: @author <a href="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>
022: @version $Revision: 1.1 $ $Date: 2003/08/18 08:19:37 $
023: */
024: public class CounterDisplay extends JPanel {
025:
026: private static final Map STYLE;
027: private static final Color COLOR_BACKGROUND = UIManager
028: .getColor("Panel.background");
029:
030: static {
031: Font baseFont = UIManager.getFont("TextArea.font");
032:
033: STYLE = new HashMap(3);
034: STYLE.put(TextAttribute.FAMILY, baseFont.getFamily());
035: STYLE
036: .put(TextAttribute.SIZE, new Float(
037: baseFont.getSize() - 2));
038: STYLE.put(TextAttribute.FOREGROUND, new Color(92, 92, 92));
039: }
040:
041: private int maxCount;
042: private int lineHeight;
043: private int ascent;
044:
045: private int maxChars;
046: private FontRenderContext frc;
047:
048: /**
049: * Constructor.
050: */
051: public CounterDisplay() {
052: setBorder(ByteCodeDisplay.BORDER);
053: setDoubleBuffered(false);
054: setOpaque(false);
055: }
056:
057: /**
058: * Initialize with the properties of a given bytecode display.
059: * @param byteCodeDisplay the bytecode display.
060: */
061: public void init(ByteCodeDisplay byteCodeDisplay) {
062:
063: this .maxCount = byteCodeDisplay.getLineCount();
064: this .lineHeight = byteCodeDisplay.getLineHeight();
065: this .ascent = byteCodeDisplay.getAscent();
066:
067: frc = ((Graphics2D) getGraphics()).getFontRenderContext();
068: maxChars = Math.max(1, String.valueOf(maxCount).length());
069:
070: TextLayout textLayout = new TextLayout(
071: getCharacterIterator(maxCount), frc);
072:
073: setPreferredSize(new Dimension((int) textLayout.getAdvance()
074: + 2 * ByteCodeDisplay.MARGIN_X, maxCount * lineHeight
075: + 2 * ByteCodeDisplay.MARGIN_Y));
076: invalidate();
077: }
078:
079: private AttributedCharacterIterator getCharacterIterator(int number) {
080: AttributedString attrSting = new AttributedString(
081: ByteCodeDisplay.getPaddedValue(number, maxChars), STYLE);
082:
083: return attrSting.getIterator();
084: }
085:
086: protected void paintComponent(Graphics graphics) {
087:
088: if (maxCount == 0 || lineHeight == 0) {
089: return;
090: }
091:
092: Graphics2D g = (Graphics2D) graphics;
093: g.translate(ByteCodeDisplay.MARGIN_X, ByteCodeDisplay.MARGIN_Y);
094: Rectangle clipBounds = graphics.getClipBounds();
095: Paint oldPaint = g.getPaint();
096: g.setPaint(COLOR_BACKGROUND);
097: g.fill(clipBounds);
098: g.setPaint(oldPaint);
099:
100: int startLine = Math.max(0, clipBounds.y / lineHeight - 1);
101: int endLine = Math.min(maxCount,
102: (clipBounds.y + clipBounds.height) / lineHeight + 1);
103: for (int i = startLine; i < endLine; i++) {
104: TextLayout textLayout = new TextLayout(
105: getCharacterIterator(i + 1), frc);
106: textLayout.draw(g, 0, i * lineHeight + ascent);
107: }
108:
109: g.translate(-ByteCodeDisplay.MARGIN_X,
110: -ByteCodeDisplay.MARGIN_Y);
111: }
112: }
|