/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille * * ludovic.apvrille AT enst.fr * * This software is a computer program whose purpose is to allow the * edition of TURTLE analysis, design and deployment diagrams, to * allow the generation of RT-LOTOS or Java code from this diagram, * and at last to allow the analysis of formal validation traces * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP * from INRIA Rhone-Alpes. * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. */ package ui.sysmlv2; import java.awt.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.text.*; import myutil.*; /** * Class LineNumber * Sysmlv2 edition * Creation: 15/07/2021 * @version 1.0 15/07/2021 * @author Ludovic APVRILLE */ public class LineNumber extends JComponent { private final static Color DEFAULT_BACKGROUND = new Color(235, 230, 225); 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; private JPanelForEdition jpfe; /** * Convenience constructor for Text Components */ public LineNumber(JComponent component, JPanelForEdition _jpfe) { if (component == null) { setFont( DEFAULT_FONT ); this.component = this; } else { setFont( component.getFont() ); this.component = component; } jpfe = _jpfe; 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; int selectedLine = jpfe.getSelectedLine(); Color c = g.getColor(); for (int i = startLineNumber; i <= endLineNumber; i++) { int lineNumber = jpfe.getIntCorrespondance(i); //TraceManager.addDev("LineNumber: start=" + startLineNumber + " end=" + endLineNumber + " result at " + i + " = " + lineNumber); if (lineNumber > -10) { int rowWidth = getSize().width; if (lineNumber == -4) { g.drawLine(rowWidth - (2*MARGIN), start-lineHeight+1, rowWidth - (2*MARGIN), start); } else if (lineNumber == -3) { g.drawLine(rowWidth - (2*MARGIN), start-lineHeight+1, rowWidth - (2*MARGIN), start-(lineHeight / 10)); g.drawLine(rowWidth - (2*MARGIN), start-(lineHeight / 10), rowWidth - MARGIN, start-(lineHeight / 10)); } else { //String lineNumber = String.valueOf(jpfe.getCorrespondance(i)); //String lineNumber = String.valueOf(i); int stringWidth = fontMetrics.stringWidth(""+lineNumber); if (lineNumber==selectedLine) { g.setColor(Color.MAGENTA); g.fillRect(0, start-lineHeight+3, rowWidth, lineHeight); g.setColor(Color.GREEN); } g.drawString(""+lineNumber, rowWidth - stringWidth - MARGIN, start); g.setColor(c); } } start += lineHeight; } int rows = component.getSize().height / componentFontHeight; setPreferredWidth( rows ); } }