com.github.croesch.micro_debug.gui.components.code.LineNumberLabel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of micro-debug-gui Show documentation
Show all versions of micro-debug-gui Show documentation
A GUI for the micro-debug - a debugger for (micro-)assembler-programs for the Mic-1.
The newest version!
/*
* Copyright (C) 2011-2012 Christian Roesch
*
* This file is part of micro-debug-gui.
*
* micro-debug-gui is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* micro-debug-gui 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with micro-debug-gui. If not, see .
*/
package com.github.croesch.micro_debug.gui.components.code;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import com.github.croesch.micro_debug.annotation.NotNull;
import com.github.croesch.micro_debug.commons.Utils;
import com.github.croesch.micro_debug.gui.components.basic.MDLabel;
import com.github.croesch.micro_debug.gui.debug.LineNumberMapper;
/**
* Vertical row view that shows line numbers for a given text component.
*
* @author croesch
* @since Date: Mar 19, 2012
*/
public class LineNumberLabel extends MDLabel implements DocumentListener {
/** generated serial version UID */
private static final long serialVersionUID = -5234458420083482975L;
/** the number of the line that is highlighted */
private int highlightedLine = -1;
/** the text component this component shows the line numbers for */
@NotNull
private final ACodeArea textArea;
/** the abstraction layer that maps real line numbers to line numbers for the user */
@NotNull
private final transient LineNumberMapper lineNumberMapper;
/**
* Constructs this ruler that shows line numbers for the given component. Will update itself, when the underlying
* document of the given text component changes.
*
* @since Date: Mar 20, 2012
* @param ta the text component to show line numbers for, must not be null
.
* @param mapper instance of a mapper for line numbers that maps real internal line numbers to the representation for
* the user
*/
public LineNumberLabel(final ACodeArea ta, final LineNumberMapper mapper) {
super(ta.getName() + "-line-numbers", null);
setVerticalAlignment(SwingConstants.TOP);
this.lineNumberMapper = mapper;
this.textArea = ta;
this.textArea.getDocument().addDocumentListener(this);
manageSize();
repaint();
}
/**
* Sets the size of this component, since we choose custom painting, we have to control the minimum and preferred size
* ourselves.
*
* @since Date: Jul 14, 2012
*/
private void manageSize() {
final String highestLN = Utils.toHexString(this.lineNumberMapper.getLineForNumber(this.textArea.getLineCount() - 1));
final StringBuilder sb = new StringBuilder(highestLN.length());
sb.append("0x");
for (int i = 0; i < highestLN.length() - 2; ++i) {
sb.append('A');
}
setMinimumSize(new Dimension(getFontMetrics(getFont()).stringWidth(sb.toString()),
this.textArea.getMinimumSize().height));
// preferred - add some extra space
sb.append('.');
setPreferredSize(new Dimension(getFontMetrics(getFont()).stringWidth(sb.toString()),
this.textArea.getPreferredSize().height));
}
@Override
protected final void paintComponent(final Graphics g) {
final float fontHeight = g.getFontMetrics().getLineMetrics("0", null).getHeight();
final float lineOffset = (this.textArea.getLineHeight() - fontHeight);
for (int line = 0; line < this.textArea.getLineCount(); ++line) {
final int x = 0;
final int y = this.textArea.getLineHeight() * (line + 1);
final int width = getWidth();
if (line == this.highlightedLine) {
// insert color information for highlighted line
g.setColor(UIManager.getColor("Label.background").darker());
g.fillRect(x, y, width, this.textArea.getLineHeight());
}
g.setColor(UIManager.getColor("Label.foreground"));
final String lineNumber = Utils.toHexString(this.lineNumberMapper.getLineForNumber(line));
g.drawString(lineNumber, x, (int) (y - lineOffset) - 1);
}
}
/**
* Changes the highlight to the given line. If the given line doesn't exist, nothing will be highlighted.
* Caution: Do use carefully! Will rebuild the line numbers completely, which is not performant - especially
* for high line count.
*
* @since Date: Mar 20, 2012
* @param line the number of the line to highlight
*/
public final void highlight(final int line) {
this.highlightedLine = line;
repaint();
}
/** {@inheritDoc} */
public final void insertUpdate(final DocumentEvent e) {
repaint();
}
/** {@inheritDoc} */
public final void removeUpdate(final DocumentEvent e) {
repaint();
}
/** {@inheritDoc} */
public final void changedUpdate(final DocumentEvent e) {
// nothing to do
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy