alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SourceCodePanel.java)

This example Java source code file (SourceCodePanel.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

awt, badlocationexception, editor, event, file, gui, icon, icon_size, integer, jpanel, jtextarea, jviewport, line_no_space, net, network, rectangle, rowheader, string, stringbuffer, text

The SourceCodePanel.java Java example source code

/*
 * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.ui;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.text.BadLocationException;

/** Panel supporting loading of and scrolling through source code.
    Contains convenience routines for implementing the Editor
    interface. */

public class SourceCodePanel extends JPanel {
  private JTextArea source;
  private RowHeader header;
  private String filename;
  // Amount of white space between edges, line numbers and icons
  private static final int LINE_NO_SPACE = 4;
  // Size of icons in resources directory
  private static final int ICON_SIZE = 12;
  // Icons used in panel drawing
  private static Icon topFrameCurLine;
  private static Icon lowerFrameCurLine;
  private static Icon breakpoint;
  // State
  private int highlightedLine = -1;
  private Set/*<Integer>*/ breakpoints = new HashSet(); // Zero-based lines internally
  // Parent Editor container and EditorCommands object for setting breakpoints
  private EditorCommands comm;
  private Editor parent;

  /** Support for displaying icons and line numbers in row header of
      scroll pane */
  class RowHeader extends JPanel {
    private JViewport view;
    private boolean   showLineNumbers;
    private int       width;
    private int       rowHeight;
    private boolean   initted;

    public RowHeader() {
      super();
      initted = true;
      addHierarchyBoundsListener(new HierarchyBoundsAdapter() {
          public void ancestorResized(HierarchyEvent e) {
            recomputeSize();
          }
        });
    }

    public void paint(Graphics g) {
      super.paint(g);
      if (getShowLineNumbers()) {
        // Visible region of header panel, in coordinate system of the
        // panel, is provided by clip bounds of Graphics object. This
        // is used to figure out which line numbers to draw.
        Rectangle clip = g.getClipBounds();
        // To avoid missing lines, round down starting line number and
        // round up ending line number
        int start = clip.y / rowHeight;
        int end   = start + (clip.height + (rowHeight - 1)) / rowHeight;
        // Draw these line numbers, right justified to look better
        FontMetrics fm = getFontMetrics(getFont());
        int ascent = fm.getMaxAscent(); // Causes proper alignment -- trial-and-error
        for (int i = start; i <= end; i++) {
          // Line numbers are 1-based
          String str = Integer.toString(i + 1);
          int strWidth = GraphicsUtilities.getStringWidth(str, fm);
          g.drawString(str, width - strWidth - LINE_NO_SPACE, ascent + rowHeight * i);

          // Draw breakpoint if necessary
          if (breakpoints.contains(new Integer(i))) {
            breakpoint.paintIcon(this, g, LINE_NO_SPACE, rowHeight * i);
          }

          // Draw current line icon if necessary
          if (i == highlightedLine) {
            // FIXME: use correct icon (not always topmost frame)
            topFrameCurLine.paintIcon(this, g, LINE_NO_SPACE, rowHeight * i);
          }
        }
      }
    }

    public boolean getShowLineNumbers() {
      return showLineNumbers;
    }

    public void setShowLineNumbers(boolean val) {
      if (val != showLineNumbers) {
        showLineNumbers = val;
        recomputeSize();
        // Force re-layout
        invalidate();
        validate();
      }
    }

    public void setFont(Font f) {
      super.setFont(f);
      rowHeight = getFontMetrics(f).getHeight();
      recomputeSize();
    }

    void setViewport(JViewport view) {
      this.view = view;
    }

    void recomputeSize() {
      if (!initted) return;
      if (view == null) return;
      width = ICON_SIZE + 2 * LINE_NO_SPACE;
      try {
        int numLines = 1 + source.getLineOfOffset(source.getDocument().getEndPosition().getOffset() - 1);
        String str = Integer.toString(numLines);
        if (getShowLineNumbers()) {
          // Compute width based on whether we are drawing line numbers
          width += GraphicsUtilities.getStringWidth(str, getFontMetrics(getFont())) + LINE_NO_SPACE;
        }
        // FIXME: add on width for all icons (breakpoint, current line,
        // current line in caller frame)
        Dimension d = new Dimension(width, numLines * getFontMetrics(getFont()).getHeight());
        setSize(d);
        setPreferredSize(d);
      } catch (BadLocationException e) {
        e.printStackTrace();
      }
    }
  }

  public SourceCodePanel() {
    maybeLoadIcons();

    // Build user interface
    setLayout(new BorderLayout());
    source = new JTextArea();
    source.setEditable(false);
    source.getCaret().setVisible(true);
    header = new RowHeader();
    header.setShowLineNumbers(true);
    JScrollPane scroller = new JScrollPane(source);
    JViewport rowView = new JViewport();
    rowView.setView(header);
    header.setViewport(rowView);
    rowView.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
    scroller.setRowHeader(rowView);
    add(scroller, BorderLayout.CENTER);
    // Reset font now that header and source are present
    setFont(getFont());

    source.addFocusListener(new FocusAdapter() {
        public void focusGained(FocusEvent e) {
          source.getCaret().setVisible(true);
        }
      });

    source.addKeyListener(new KeyAdapter() {
        public void keyPressed(KeyEvent e) {
          if (e.getKeyCode() == KeyEvent.VK_F9) {
            int lineNo = getCurrentLineNumber();
            // Only the debugger can figure out whether we are setting
            // or clearing a breakpoint, since it has the debug
            // information available and knows whether we're on a
            // valid line
            comm.toggleBreakpointAtLine(parent, lineNo);
          }
        }
      });

  }

  public void setFont(Font f) {
    super.setFont(f);
    if (source != null) {
      source.setFont(f);
    }
    if (header != null) {
      header.setFont(f);
    }
  }

  public boolean getShowLineNumbers() {
    return header.getShowLineNumbers();
  }

  public void setShowLineNumbers(boolean val) {
    header.setShowLineNumbers(val);
  }

  public boolean openFile(String filename) {
    try {
      this.filename = filename;
      File file = new File(filename);
      int len = (int) file.length();
      StringBuffer buf = new StringBuffer(len); // Approximation
      char[] tmp = new char[4096];
      FileReader in = new FileReader(file);
      int res = 0;
      do {
        res = in.read(tmp, 0, tmp.length);
        if (res >= 0) {
          buf.append(tmp, 0, res);
        }
      } while (res != -1);
      in.close();
      String text = buf.toString();
      source.setText(text);
      header.recomputeSize();
      return true;
    } catch (IOException e) {
      return false;
    }
  }

  public String getSourceFileName() {
    return filename;
  }

  /** Line number is one-based */
  public int getCurrentLineNumber() {
    try {
      return 1 + source.getLineOfOffset(source.getCaretPosition());
    } catch (BadLocationException e) {
      return 0;
    }
  }

  /** Line number is one-based */
  public void showLineNumber(int lineNo) {
    try {
      int offset = source.getLineStartOffset(lineNo - 1);
      Rectangle rect = source.modelToView(offset);
      if (rect == null) {
        return;
      }
      source.scrollRectToVisible(rect);
    } catch (BadLocationException e) {
      e.printStackTrace();
    }
  }

  /** Line number is one-based */
  public void highlightLineNumber(int lineNo) {
    highlightedLine = lineNo - 1;
  }

  public void showBreakpointAtLine(int lineNo)  { breakpoints.add(new Integer(lineNo - 1));    repaint(); }
  public boolean hasBreakpointAtLine(int lineNo){ return breakpoints.contains(new Integer(lineNo - 1));   }
  public void clearBreakpointAtLine(int lineNo) { breakpoints.remove(new Integer(lineNo - 1)); repaint(); }
  public void clearBreakpoints()                { breakpoints.clear();                         repaint(); }

  public void setEditorCommands(EditorCommands comm, Editor parent) {
    this.comm = comm;
    this.parent = parent;
  }

  public void requestFocus() {
    source.requestFocus();
  }

  //----------------------------------------------------------------------
  // Internals only below this point
  //

  private void maybeLoadIcons() {
    if (topFrameCurLine == null) {
      topFrameCurLine   = loadIcon("resources/arrow.png");
      lowerFrameCurLine = loadIcon("resources/triangle.png");
      breakpoint        = loadIcon("resources/breakpoint.png");
    }
  }

  private Icon loadIcon(String which) {
    URL url = getClass().getResource(which);
    return new ImageIcon(url);
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java SourceCodePanel.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.