diff --git a/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/LinesComponent.java b/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/LinesComponent.java index 2a020250c18e..966b604e64ef 100644 --- a/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/LinesComponent.java +++ b/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/LinesComponent.java @@ -39,13 +39,13 @@ import org.netbeans.api.editor.settings.AttributesUtilities; import org.netbeans.api.editor.settings.FontColorNames; import org.netbeans.api.editor.settings.FontColorSettings; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.netbeans.editor.Coloring; import org.netbeans.editor.EditorUI; import org.netbeans.editor.FontMetricsCache; import org.netbeans.lib.editor.util.swing.DocumentUtilities; +import org.openide.awt.GraphicsUtils; import org.openide.util.WeakListeners; /** GlyphGutter is component for displaying line numbers and annotation @@ -60,51 +60,52 @@ public class LinesComponent extends JComponent implements javax.accessibility.Accessible, PropertyChangeListener { - + /** Document to which this gutter is attached*/ - private JEditorPane editorPane; + private final JEditorPane editorPane; + + private final EditorUI editorUI; - private EditorUI editorUI; - /** Backroung color of the gutter */ private Color backgroundColor; - + /** Foreground color of the gutter. Used for drawing line numbers. */ private Color foreColor; - + /** Font used for drawing line numbers */ private Font font; - + /** Flag whther the gutter was initialized or not. The painting is disabled till the * gutter is not initialized */ private boolean init; - + /** Width of the column used for drawing line numbers. The value contains * also line number margins. */ private int numberWidth; /** Whether the line numbers are shown or not */ private boolean showLineNumbers = true; - + /** The gutter height is enlarged by number of lines which specifies this constant */ private static final int ENLARGE_GUTTER_HEIGHT = 300; - + /** The hightest line number. This value is used for calculating width of the gutter */ private int highestLineNumber = 0; /** Holds value of property lineNumberMargin. */ private Insets lineNumberMargin; - + /** Holds value of property lineNumberDigitWidth. */ private int lineNumberDigitWidth; - + private LinkedList linesList; - + /** Holds value of property activeLine. */ private int activeLine = -1; private static final long serialVersionUID = -4861542695772182147L; - + + @SuppressWarnings({"LeakingThisInConstructor", "OverridableMethodCallInConstructor"}) public LinesComponent(JEditorPane pane) { super(); init = false; @@ -139,18 +140,18 @@ protected void init() { getAccessibleContext().setAccessibleName(NbBundle.getMessage(LinesComponent.class, "ACSN_Lines_Component")); // NOI18N getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(LinesComponent.class, "ACSD_Lines_Component")); // NOI18N } - + private void createLines() { - linesList = new LinkedList(); + linesList = new LinkedList<>(); int lineCnt; StyledDocument doc = (StyledDocument)editorPane.getDocument(); int lastOffset = doc.getEndPosition().getOffset(); - lineCnt = org.openide.text.NbDocument.findLineNumber(doc, lastOffset); + lineCnt = org.openide.text.NbDocument.findLineNumber(doc, lastOffset); for (int i = 0; i < lineCnt; i++) { linesList.add(Integer.toString(i + 1)); } } - + public void addEmptyLines(int line, int count) { boolean appending = line > linesList.size(); for (int i = 0; i < count; i++) { @@ -161,11 +162,12 @@ public void addEmptyLines(int line, int count) { } } } - + /** * Insert line numbers. If at the end, then line numbers are added to the end of the component. * If in the middle, subsequent lines are overwritten. */ + @SuppressWarnings("AssignmentToMethodParameter") public void insertNumbers(int line, int startNum, int count) { boolean appending = line >= linesList.size(); if (appending) { @@ -183,7 +185,7 @@ public void insertNumbers(int line, int startNum, int count) { } } } - + /* * Test method. * @@ -196,12 +198,13 @@ private void dumpResultLineNumbers() { System.out.println(""); } */ - + /** * Remove line numbers and leave the corresponding part of the lines component empty. * If at the end, then an empty space is added to the end of the component. * If in the middle, subsequent lines are overwritten by an empty space. */ + @SuppressWarnings("AssignmentToMethodParameter") public void removeNumbers(int line, int count) { boolean appending = line >= linesList.size(); if (appending) { @@ -219,7 +222,7 @@ public void removeNumbers(int line, int count) { } } } - + /** * Shrink the component, so that it will have numLines number of lines. * @param numLines The new number of lines @@ -229,7 +232,7 @@ public void shrink(int numLines) { linesList.remove(numLines); } } - + /** Update colors, fonts, sizes and invalidate itself. This method is * called from EditorUI.update() */ private void updateState(Graphics g) { @@ -239,11 +242,11 @@ private void updateState(Graphics g) { Coloring col = Coloring.fromAttributeSet(AttributesUtilities.createComposite( fcs.getFontColors(FontColorNames.LINE_NUMBER_COLORING), fcs.getFontColors(FontColorNames.DEFAULT_COLORING))); - + foreColor = col.getForeColor(); backgroundColor = col.getBackColor(); //System.out.println(" => foreground = "+foreColor+", background = "+backgroundColor); - + font = col.getFont(); FontMetrics fm = g.getFontMetrics(font); /* @@ -288,19 +291,19 @@ private void updateState(Graphics g) { setLineNumberDigitWidth(maxWidth); // System.out.println("maxwidth=" + maxWidth); // System.out.println("numner of lines=" + highestLineNumber); - + resize(); } - + protected void resize() { Dimension dim = new Dimension(); // System.out.println("resizing..................."); dim.width = getWidthDimension(); dim.height = getHeightDimension(); - // enlarge the gutter so that inserting new lines into + // enlarge the gutter so that inserting new lines into // document does not cause resizing too often dim.height += ENLARGE_GUTTER_HEIGHT * editorUI.getLineHeight(); - + numberWidth = getLineNumberWidth(); setPreferredSize(dim); @@ -330,14 +333,14 @@ protected int getLineNumberWidth() { protected int getWidthDimension() { int newWidth = 0; - + if (showLineNumbers) { newWidth += getLineNumberWidth(); } return newWidth; } - + protected int getHeightDimension() { /*TEMP+ (int)editorPane.getSize().getHeight() */ View rootView = org.netbeans.editor.Utilities.getDocumentView(editorPane); @@ -355,7 +358,7 @@ protected int getHeightDimension() { } return height; } - + /** Paint the gutter itself */ public @Override void paintComponent(Graphics g) { @@ -363,15 +366,16 @@ protected int getHeightDimension() { if (!init) { updateState(g); } - // return; - + + GraphicsUtils.configureDefaultRenderingHints(g); + Rectangle drawHere = g.getClipBounds(); // Fill clipping area with dirty brown/orange. g.setColor(backgroundColor); g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height); - g.setFont(font); + g.setFont(font); g.setColor(foreColor); FontMetrics fm = FontMetricsCache.getFontMetrics(font, this); @@ -418,10 +422,10 @@ protected int getHeightDimension() { String activeSymbol = "*"; //NOI18N int lineNumberWidth = fm.stringWidth(lineStr); if (line == activeLine - 1) { - lineStr = lineStr + activeSymbol; + lineStr += activeSymbol; } int activeSymbolWidth = fm.stringWidth(activeSymbol); - lineNumberWidth = lineNumberWidth + activeSymbolWidth; + lineNumberWidth += activeSymbolWidth; g.drawString(lineStr, numberWidth - lineNumberWidth - rightMargin, y + lineAscent); } @@ -429,7 +433,6 @@ protected int getHeightDimension() { line++; } } catch (BadLocationException ex) { - return; } } @@ -462,42 +465,42 @@ protected void checkSize() { resize(); } } - + /** Getter for property lineNumberMargin. * @return Value of property lineNumberMargin. */ public Insets getLineNumberMargin() { return this.lineNumberMargin; } - + /** Setter for property lineNumberMargin. * @param lineNumberMargin New value of property lineNumberMargin. */ public void setLineNumberMargin(Insets lineNumberMargin) { this.lineNumberMargin = lineNumberMargin; } - + /** Getter for property lineNumberDigitWidth. * @return Value of property lineNumberDigitWidth. */ public int getLineNumberDigitWidth() { return this.lineNumberDigitWidth; } - + /** Setter for property lineNumberDigitWidth. * @param lineNumberDigitWidth New value of property lineNumberDigitWidth. */ public void setLineNumberDigitWidth(int lineNumberDigitWidth) { this.lineNumberDigitWidth = lineNumberDigitWidth; } - + /** Getter for property activeLine. * @return Value of property activeLine. */ public int getActiveLine() { return this.activeLine; } - + /** Setter for property activeLine. * @param activeLine New value of property activeLine. */ @@ -505,6 +508,7 @@ public void setActiveLine(int activeLine) { this.activeLine = activeLine; } + @Override public void propertyChange(PropertyChangeEvent evt) { init = false; repaint(); diff --git a/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/editable/LineNumbersActionsBar.java b/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/editable/LineNumbersActionsBar.java index b99a4e1548c4..3aa8a45d02a9 100644 --- a/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/editable/LineNumbersActionsBar.java +++ b/ide/diff/src/org/netbeans/modules/diff/builtin/visualizer/editable/LineNumbersActionsBar.java @@ -63,7 +63,7 @@ /** * Draws both line numbers and diff actions for a decorated editor pane. - * + * * @author Maros Sandor */ class LineNumbersActionsBar extends JPanel implements Scrollable, MouseMotionListener, MouseListener, PropertyChangeListener { @@ -71,13 +71,13 @@ class LineNumbersActionsBar extends JPanel implements Scrollable, MouseMotionLis private static final int ACTIONS_BAR_WIDTH = 16; private static final int LINES_BORDER_WIDTH = 4; private static final Point POINT_ZERO = new Point(0, 0); - + private final Icon insertIcon = ImageUtilities.loadIcon("org/netbeans/modules/diff/builtin/visualizer/editable/insert.png"); // NOI18N private final Icon removeIcon = ImageUtilities.loadIcon("org/netbeans/modules/diff/builtin/visualizer/editable/remove.png"); // NOI18N private final Icon insertActiveIcon = ImageUtilities.loadIcon("org/netbeans/modules/diff/builtin/visualizer/editable/insert_active.png"); // NOI18N private final Icon removeActiveIcon = ImageUtilities.loadIcon("org/netbeans/modules/diff/builtin/visualizer/editable/remove_active.png"); // NOI18N - + private final DiffContentPanel master; private final boolean actionsEnabled; private final int actionIconsHeight; @@ -85,18 +85,19 @@ class LineNumbersActionsBar extends JPanel implements Scrollable, MouseMotionLis private final String lineNumberPadding = " "; // NOI18N - private int linesWidth; - private int actionsWidth; - + private int linesWidth; + private final int actionsWidth; + private Color linesColor; private int linesCount; private int maxNumberCount; private Point lastMousePosition = POINT_ZERO; private HotSpot lastHotSpot = null; - - private List hotspots = new ArrayList(0); + private List hotspots = new ArrayList<>(0); + + @SuppressWarnings("LeakingThisInConstructor") public LineNumbersActionsBar(DiffContentPanel master, boolean actionsEnabled) { this.master = master; this.actionsEnabled = actionsEnabled; @@ -110,19 +111,22 @@ public LineNumbersActionsBar(DiffContentPanel master, boolean actionsEnabled) { addMouseListener(this); } + @Override public void addNotify() { super.addNotify(); initUI(); } + @Override public void removeNotify() { super.removeNotify(); } + @Override public void propertyChange(PropertyChangeEvent evt) { repaint(); } - + private Font getLinesFont() { String mimeType = DocumentUtilities.getMimeType(master.getEditorPane()); FontColorSettings fcs = MimeLookup.getLookup(mimeType).lookup(FontColorSettings.class); @@ -133,13 +137,13 @@ private Font getLinesFont() { } return font; } - + private void initUI() { String mimeType = DocumentUtilities.getMimeType(master.getEditorPane()); FontColorSettings fcs = MimeLookup.getLookup(mimeType).lookup(FontColorSettings.class); AttributeSet attrs = fcs.getFontColors(FontColorNames.LINE_NUMBER_COLORING); AttributeSet defAttrs = fcs.getFontColors(FontColorNames.DEFAULT_COLORING); - + linesColor = (Color) attrs.getAttribute(StyleConstants.Foreground); if (linesColor == null) { linesColor = (Color) defAttrs.getAttribute(StyleConstants.Foreground); @@ -149,7 +153,7 @@ private void initUI() { bg = (Color) defAttrs.getAttribute(StyleConstants.Background); } setBackground(bg); - + updateStateOnDocumentChange(); } @@ -161,25 +165,28 @@ private HotSpot getHotspotAt(Point p) { } return null; } - + + @Override public String getToolTipText(MouseEvent event) { Point p = event.getPoint(); HotSpot spot = getHotspotAt(p); if (spot == null) return null; Difference diff = spot.getDiff(); - if (diff.getType() == Difference.ADD) { - return NbBundle.getMessage(LineNumbersActionsBar.class, "TT_DiffPanel_Remove"); // NOI18N - } else if (diff.getType() == Difference.CHANGE) { - return NbBundle.getMessage(LineNumbersActionsBar.class, "TT_DiffPanel_Replace"); // NOI18N - } else { - return NbBundle.getMessage(LineNumbersActionsBar.class, "TT_DiffPanel_Insert"); // NOI18N - } + return switch (diff.getType()) { + case Difference.ADD -> + NbBundle.getMessage(LineNumbersActionsBar.class, "TT_DiffPanel_Remove"); // NOI18N + case Difference.CHANGE -> + NbBundle.getMessage(LineNumbersActionsBar.class, "TT_DiffPanel_Replace"); // NOI18N + default -> + NbBundle.getMessage(LineNumbersActionsBar.class, "TT_DiffPanel_Insert"); // NOI18N + }; } private void performAction(HotSpot spot) { master.getMaster().rollback(spot.getDiff()); } - + + @Override public void mouseClicked(MouseEvent e) { if (!e.isPopupTrigger()) { HotSpot spot = getHotspotAt(e.getPoint()); @@ -189,18 +196,22 @@ public void mouseClicked(MouseEvent e) { } } + @Override public void mousePressed(MouseEvent e) { // not interested } + @Override public void mouseReleased(MouseEvent e) { // not interested } + @Override public void mouseEntered(MouseEvent e) { // not interested } + @Override public void mouseExited(MouseEvent e) { lastMousePosition = POINT_ZERO; if (lastHotSpot != null) { @@ -208,7 +219,8 @@ public void mouseExited(MouseEvent e) { } lastHotSpot = null; } - + + @Override public void mouseMoved(MouseEvent e) { Point p = e.getPoint(); lastMousePosition = p; @@ -219,31 +231,32 @@ public void mouseMoved(MouseEvent e) { lastHotSpot = spot; setCursor(spot != null ? Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) : Cursor.getDefaultCursor()); } - + + @Override public void mouseDragged(MouseEvent e) { // not interested } void onUISettingsChanged() { - initUI(); + initUI(); updateStateOnDocumentChange(); repaint(); } - + private void updateStateOnDocumentChange() { assert SwingUtilities.isEventDispatchThread(); StyledDocument doc = (StyledDocument) master.getEditorPane().getDocument(); int lastOffset = doc.getEndPosition().getOffset(); - linesCount = org.openide.text.NbDocument.findLineNumber(doc, lastOffset); + linesCount = org.openide.text.NbDocument.findLineNumber(doc, lastOffset); - Graphics g = getGraphics(); + Graphics g = getGraphics(); if (g != null) checkLinesWidth(g); maxNumberCount = getNumberCount(linesCount); revalidate(); } - + private int oldLinesWidth; - + private boolean checkLinesWidth(Graphics g) { FontMetrics fm = g.getFontMetrics(getLinesFont()); Rectangle2D rect = fm.getStringBounds(Integer.toString(linesCount), g); @@ -256,34 +269,41 @@ private boolean checkLinesWidth(Graphics g) { } return false; } - - private int getNumberCount(int n) { + + @SuppressWarnings({"AssignmentToMethodParameter", "empty-statement"}) + private static int getNumberCount(int n) { int nc = 0; for (; n > 0; n /= 10, nc++); return nc; } + @Override public Dimension getPreferredScrollableViewportSize() { Dimension dim = master.getEditorPane().getPreferredScrollableViewportSize(); return new Dimension(getBarWidth(), dim.height); } + @Override public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { return master.getEditorPane().getScrollableUnitIncrement(visibleRect, orientation, direction);//123 } + @Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { return master.getEditorPane().getScrollableBlockIncrement(visibleRect, orientation, direction); } + @Override public boolean getScrollableTracksViewportWidth() { return true; } + @Override public boolean getScrollableTracksViewportHeight() { return false; } - + + @Override public Dimension getPreferredSize() { return new Dimension(getBarWidth(), Integer.MAX_VALUE >> 2); } @@ -297,23 +317,24 @@ public void onDiffSetChanged() { repaint(); } + @Override protected void paintComponent(Graphics gr) { final Graphics2D g = (Graphics2D) gr; final Rectangle clip = g.getClipBounds(); Stroke cs = g.getStroke(); if (checkLinesWidth(gr)) return; - + String mimeType = DocumentUtilities.getMimeType(master.getEditorPane()); FontColorSettings fcs = MimeLookup.getLookup(mimeType).lookup(FontColorSettings.class); Map renderingHints = (Map) fcs.getFontColors(FontColorNames.DEFAULT_COLORING).getAttribute(EditorStyleConstants.RenderingHints); if (!renderingHints.isEmpty()) { g.addRenderingHints(renderingHints); } - + EditorUI editorUI = org.netbeans.editor.Utilities.getEditorUI(master.getEditorPane()); final int lineHeight = editorUI.getLineHeight(); - + g.setColor(getBackground()); g.fillRect(clip.x, clip.y, clip.width, clip.height); @@ -327,16 +348,16 @@ protected void paintComponent(Graphics gr) { int offset = linesWidth; int currentDifference = master.getMaster().getCurrentDifference(); - List newActionIcons = new ArrayList(); + List newActionIcons = new ArrayList<>(); int idx = 0; for (DiffViewManager.DecoratedDifference dd : diffs) { int bottom = master.isFirst() ? dd.getBottomLeft() : dd.getBottomRight(); int top = master.isFirst() ? dd.getTopLeft() : dd.getTopRight(); g.setColor(master.getMaster().getColorLines()); g.setStroke(currentDifference == idx ? master.getMaster().getBoldStroke() : cs); - g.drawLine(0, top, clip.width, top); + g.drawLine(0, top, getBarWidth(), top); if (bottom != -1) { - g.drawLine(0, bottom, clip.width, bottom); + g.drawLine(0, bottom, getBarWidth(), bottom); } if (actionsEnabled && dd.canRollback()) { if (master.isFirst() && dd.getDiff().getType() != Difference.ADD @@ -355,60 +376,57 @@ protected void paintComponent(Graphics gr) { idx++; } hotspots = newActionIcons; - + final int linesXOffset = (master.isFirst() ? actionsWidth : 0) + LINES_BORDER_WIDTH; - - g.setFont(getLinesFont()); + + g.setFont(getLinesFont()); g.setColor(linesColor); - - Utilities.runViewHierarchyTransaction(master.getEditorPane(), true, new Runnable() { - @Override - public void run() { - try { - View rootView = Utilities.getDocumentView(master.getEditorPane()); - if(rootView == null) { // this might happen - return; - } - int lineNumber = Utilities.getLineOffset((BaseDocument) master.getEditorPane().getDocument(), master.getEditorPane().viewToModel(new Point(clip.x, clip.y))); - if (lineNumber > 0) { - --lineNumber; - } - View view = rootView.getView(lineNumber); - if(view == null) { // this might happen - return; - } - Rectangle rec = master.getEditorPane().modelToView(view.getStartOffset()); - if (rec == null) { - return; - } - int yOffset; - int localLineHeight = rec.height; - int linesDrawn = clip.height / localLineHeight + 4; // draw past clipping rectangle to avoid partially drawn numbers - int docLines = Utilities.getRowCount((BaseDocument) master.getEditorPane().getDocument()); - if (lineNumber + linesDrawn > docLines) { - linesDrawn = docLines - lineNumber; + + Utilities.runViewHierarchyTransaction(master.getEditorPane(), true, () -> { + try { + View rootView = Utilities.getDocumentView(master.getEditorPane()); + if(rootView == null) { // this might happen + return; + } + int lineNumber = Utilities.getLineOffset((BaseDocument) master.getEditorPane().getDocument(), master.getEditorPane().viewToModel(new Point(clip.x, clip.y))); + if (lineNumber > 0) { + --lineNumber; + } + View view = rootView.getView(lineNumber); + if(view == null) { // this might happen + return; + } + Rectangle rec = master.getEditorPane().modelToView(view.getStartOffset()); + if (rec == null) { + return; + } + int yOffset; + int localLineHeight = rec.height; + int linesDrawn = clip.height / localLineHeight + 4; // draw past clipping rectangle to avoid partially drawn numbers + int docLines = Utilities.getRowCount((BaseDocument) master.getEditorPane().getDocument()); + if (lineNumber + linesDrawn > docLines) { + linesDrawn = docLines - lineNumber; + } + for (int i = 0; i < linesDrawn; i++) { + view = rootView.getView(lineNumber); + if (view == null) { + break; } - for (int i = 0; i < linesDrawn; i++) { - view = rootView.getView(lineNumber); - if (view == null) { - break; - } - Rectangle rec1 = master.getEditorPane().modelToView(view.getStartOffset()); - Rectangle rec2 = master.getEditorPane().modelToView(view.getEndOffset() - 1); - if (rec1 == null || rec2 == null) { - break; - } - yOffset = rec1.y + rec1.height - rec1.height / 4; - localLineHeight = (int) (rec2.getY() + rec2.getHeight() - rec1.getY()); - g.drawString(formatLineNumber(++lineNumber), linesXOffset, yOffset); + Rectangle rec1 = master.getEditorPane().modelToView(view.getStartOffset()); + Rectangle rec2 = master.getEditorPane().modelToView(view.getEndOffset() - 1); + if (rec1 == null || rec2 == null) { + break; } - } catch (BadLocationException ex) { - // + yOffset = rec1.y + rec1.height - rec1.height / 4; + lineNumber++; + g.drawString(formatLineNumber(lineNumber), linesXOffset, yOffset); } + } catch (BadLocationException ex) { + // } }); } - + private String formatLineNumber(int lineNumber) { String strNumber = Integer.toString(lineNumber); int nc = getNumberCount(lineNumber);