Java Source code Viewer : Editor « SWT JFace Eclipse « Java






Java Source code Viewer

Java Source code Viewer


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.Hashtable;
import java.util.ResourceBundle;
import java.util.Vector;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;

/**
 */
public class JavaViewer {
  Shell shell;

  StyledText text;

  JavaLineStyler lineStyler = new JavaLineStyler();

  FileDialog fileDialog;

  Menu createFileMenu() {
    Menu bar = shell.getMenuBar();
    Menu menu = new Menu(bar);
    MenuItem item;

    // Open
    item = new MenuItem(menu, SWT.CASCADE);
    item.setText("Open");
    item.setAccelerator(SWT.MOD1 + 'O');
    item.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent event) {
        openFile();
      }
    });

    // Exit
    item = new MenuItem(menu, SWT.PUSH);
    item.setText("Exit");
    item.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        menuFileExit();
      }
    });
    return menu;
  }

  void createMenuBar() {
    Menu bar = new Menu(shell, SWT.BAR);
    shell.setMenuBar(bar);

    MenuItem fileItem = new MenuItem(bar, SWT.CASCADE);
    fileItem.setText("File");
    fileItem.setMenu(createFileMenu());

  }

  void createShell(Display display) {
    shell = new Shell(display);
    shell.setText("Window");
    GridLayout layout = new GridLayout();
    layout.numColumns = 1;
    shell.setLayout(layout);
    shell.addShellListener(new ShellAdapter() {
      public void shellClosed(ShellEvent e) {
        lineStyler.disposeColors();
        text.removeLineStyleListener(lineStyler);
      }
    });
  }

  void createStyledText() {
    text = new StyledText(shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL
        | SWT.H_SCROLL);
    GridData spec = new GridData();
    spec.horizontalAlignment = GridData.FILL;
    spec.grabExcessHorizontalSpace = true;
    spec.verticalAlignment = GridData.FILL;
    spec.grabExcessVerticalSpace = true;
    text.setLayoutData(spec);
    text.addLineStyleListener(lineStyler);
    text.setEditable(false);
    Color bg = Display.getDefault().getSystemColor(SWT.COLOR_GRAY);
    text.setBackground(bg);
  }

  void displayError(String msg) {
    MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
    box.setMessage(msg);
    box.open();
  }

  public static void main(String[] args) {
    Display display = new Display();
    JavaViewer example = new JavaViewer();
    Shell shell = example.open(display);
    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();
    display.dispose();
  }

  public Shell open(Display display) {
    createShell(display);
    createMenuBar();
    createStyledText();
    shell.setSize(500, 400);
    shell.open();
    return shell;
  }

  void openFile() {
    if (fileDialog == null) {
      fileDialog = new FileDialog(shell, SWT.OPEN);
    }

    fileDialog.setFilterExtensions(new String[] { "*.java", "*.*" });
    String name = fileDialog.open();

    open(name);
  }

  void open(String name) {
    final String textString;

    if ((name == null) || (name.length() == 0))
      return;

    File file = new File(name);
    if (!file.exists()) {
      String message = "Err file no exist";
      displayError(message);
      return;
    }

    try {
      FileInputStream stream = new FileInputStream(file.getPath());
      try {
        Reader in = new BufferedReader(new InputStreamReader(stream));
        char[] readBuffer = new char[2048];
        StringBuffer buffer = new StringBuffer((int) file.length());
        int n;
        while ((n = in.read(readBuffer)) > 0) {
          buffer.append(readBuffer, 0, n);
        }
        textString = buffer.toString();
        stream.close();
      } catch (IOException e) {
        // Err_file_io
        String message = "Err_file_io";
        displayError(message);
        return;
      }
    } catch (FileNotFoundException e) {
      String message = "Err_not_found";
      displayError(message);
      return;
    }
    // Guard against superfluous mouse move events -- defer action until
    // later
    Display display = text.getDisplay();
    display.asyncExec(new Runnable() {
      public void run() {
        text.setText(textString);
      }
    });

    // parse the block comments up front since block comments can go across
    // lines - inefficient way of doing this
    lineStyler.parseBlockComments(textString);
  }

  void menuFileExit() {
    shell.close();
  }
}

/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: IBM Corporation - initial API and implementation
 ******************************************************************************/

class JavaLineStyler implements LineStyleListener {
  JavaScanner scanner = new JavaScanner();

  int[] tokenColors;

  Color[] colors;

  Vector blockComments = new Vector();

  public static final int EOF = -1;

  public static final int EOL = 10;

  public static final int WORD = 0;

  public static final int WHITE = 1;

  public static final int KEY = 2;

  public static final int COMMENT = 3;

  public static final int STRING = 5;

  public static final int OTHER = 6;

  public static final int NUMBER = 7;

  public static final int MAXIMUM_TOKEN = 8;

  public JavaLineStyler() {
    initializeColors();
    scanner = new JavaScanner();
  }

  Color getColor(int type) {
    if (type < 0 || type >= tokenColors.length) {
      return null;
    }
    return colors[tokenColors[type]];
  }

  boolean inBlockComment(int start, int end) {
    for (int i = 0; i < blockComments.size(); i++) {
      int[] offsets = (int[]) blockComments.elementAt(i);
      // start of comment in the line
      if ((offsets[0] >= start) && (offsets[0] <= end))
        return true;
      // end of comment in the line
      if ((offsets[1] >= start) && (offsets[1] <= end))
        return true;
      if ((offsets[0] <= start) && (offsets[1] >= end))
        return true;
    }
    return false;
  }

  void initializeColors() {
    Display display = Display.getDefault();
    colors = new Color[] { new Color(display, new RGB(0, 0, 0)), // black
        new Color(display, new RGB(255, 0, 0)), // red
        new Color(display, new RGB(0, 255, 0)), // green
        new Color(display, new RGB(0, 0, 255)) // blue
    };
    tokenColors = new int[MAXIMUM_TOKEN];
    tokenColors[WORD] = 0;
    tokenColors[WHITE] = 0;
    tokenColors[KEY] = 3;
    tokenColors[COMMENT] = 1;
    tokenColors[STRING] = 2;
    tokenColors[OTHER] = 0;
    tokenColors[NUMBER] = 0;
  }

  void disposeColors() {
    for (int i = 0; i < colors.length; i++) {
      colors[i].dispose();
    }
  }

  /**
   * Event.detail line start offset (input) Event.text line text (input)
   * LineStyleEvent.styles Enumeration of StyleRanges, need to be in order.
   * (output) LineStyleEvent.background line background color (output)
   */
  public void lineGetStyle(LineStyleEvent event) {
    Vector styles = new Vector();
    int token;
    StyleRange lastStyle;
    // If the line is part of a block comment, create one style for the
    // entire line.
    if (inBlockComment(event.lineOffset, event.lineOffset
        + event.lineText.length())) {
      styles.addElement(new StyleRange(event.lineOffset, event.lineText
          .length(), getColor(COMMENT), null));
      event.styles = new StyleRange[styles.size()];
      styles.copyInto(event.styles);
      return;
    }
    Color defaultFgColor = ((Control) event.widget).getForeground();
    scanner.setRange(event.lineText);
    token = scanner.nextToken();
    while (token != EOF) {
      if (token == OTHER) {
        // do nothing for non-colored tokens
      } else if (token != WHITE) {
        Color color = getColor(token);
        // Only create a style if the token color is different than the
        // widget's default foreground color and the token's style is
        // not
        // bold. Keywords are bolded.
        if ((!color.equals(defaultFgColor)) || (token == KEY)) {
          StyleRange style = new StyleRange(scanner.getStartOffset()
              + event.lineOffset, scanner.getLength(), color,
              null);
          if (token == KEY) {
            style.fontStyle = SWT.BOLD;
          }
          if (styles.isEmpty()) {
            styles.addElement(style);
          } else {
            // Merge similar styles. Doing so will improve
            // performance.
            lastStyle = (StyleRange) styles.lastElement();
            if (lastStyle.similarTo(style)
                && (lastStyle.start + lastStyle.length == style.start)) {
              lastStyle.length += style.length;
            } else {
              styles.addElement(style);
            }
          }
        }
      } else if ((!styles.isEmpty())
          && ((lastStyle = (StyleRange) styles.lastElement()).fontStyle == SWT.BOLD)) {
        int start = scanner.getStartOffset() + event.lineOffset;
        lastStyle = (StyleRange) styles.lastElement();
        // A font style of SWT.BOLD implies that the last style
        // represents a java keyword.
        if (lastStyle.start + lastStyle.length == start) {
          // Have the white space take on the style before it to
          // minimize the number of style ranges created and the
          // number of font style changes during rendering.
          lastStyle.length += scanner.getLength();
        }
      }
      token = scanner.nextToken();
    }
    event.styles = new StyleRange[styles.size()];
    styles.copyInto(event.styles);
  }

  public void parseBlockComments(String text) {
    blockComments = new Vector();
    StringReader buffer = new StringReader(text);
    int ch;
    boolean blkComment = false;
    int cnt = 0;
    int[] offsets = new int[2];
    boolean done = false;

    try {
      while (!done) {
        switch (ch = buffer.read()) {
        case -1: {
          if (blkComment) {
            offsets[1] = cnt;
            blockComments.addElement(offsets);
          }
          done = true;
          break;
        }
        case '/': {
          ch = buffer.read();
          if ((ch == '*') && (!blkComment)) {
            offsets = new int[2];
            offsets[0] = cnt;
            blkComment = true;
            cnt++;
          } else {
            cnt++;
          }
          cnt++;
          break;
        }
        case '*': {
          if (blkComment) {
            ch = buffer.read();
            cnt++;
            if (ch == '/') {
              blkComment = false;
              offsets[1] = cnt;
              blockComments.addElement(offsets);
            }
          }
          cnt++;
          break;
        }
        default: {
          cnt++;
          break;
        }
        }
      }
    } catch (IOException e) {
      // ignore errors
    }
  }

  /**
   * A simple fuzzy scanner for Java
   */
  public class JavaScanner {

    protected Hashtable fgKeys = null;

    protected StringBuffer fBuffer = new StringBuffer();

    protected String fDoc;

    protected int fPos;

    protected int fEnd;

    protected int fStartToken;

    protected boolean fEofSeen = false;

    private String[] fgKeywords = { "abstract", "boolean", "break", "byte",
        "case", "catch", "char", "class", "continue", "default", "do",
        "double", "else", "extends", "false", "final", "finally",
        "float", "for", "if", "implements", "import", "instanceof",
        "int", "interface", "long", "native", "new", "null", "package",
        "private", "protected", "public", "return", "short", "static",
        "super", "switch", "synchronized", "this", "throw", "throws",
        "transient", "true", "try", "void", "volatile", "while" };

    public JavaScanner() {
      initialize();
    }

    /**
     * Returns the ending location of the current token in the document.
     */
    public final int getLength() {
      return fPos - fStartToken;
    }

    /**
     * Initialize the lookup table.
     */
    void initialize() {
      fgKeys = new Hashtable();
      Integer k = new Integer(KEY);
      for (int i = 0; i < fgKeywords.length; i++)
        fgKeys.put(fgKeywords[i], k);
    }

    /**
     * Returns the starting location of the current token in the document.
     */
    public final int getStartOffset() {
      return fStartToken;
    }

    /**
     * Returns the next lexical token in the document.
     */
    public int nextToken() {
      int c;
      fStartToken = fPos;
      while (true) {
        switch (c = read()) {
        case EOF:
          return EOF;
        case '/': // comment
          c = read();
          if (c == '/') {
            while (true) {
              c = read();
              if ((c == EOF) || (c == EOL)) {
                unread(c);
                return COMMENT;
              }
            }
          } else {
            unread(c);
          }
          return OTHER;
        case '\'': // char const
          character: for (;;) {
            c = read();
            switch (c) {
            case '\'':
              return STRING;
            case EOF:
              unread(c);
              return STRING;
            case '\\':
              c = read();
              break;
            }
          }

        case '"': // string
          string: for (;;) {
            c = read();
            switch (c) {
            case '"':
              return STRING;
            case EOF:
              unread(c);
              return STRING;
            case '\\':
              c = read();
              break;
            }
          }

        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          do {
            c = read();
          } while (Character.isDigit((char) c));
          unread(c);
          return NUMBER;
        default:
          if (Character.isWhitespace((char) c)) {
            do {
              c = read();
            } while (Character.isWhitespace((char) c));
            unread(c);
            return WHITE;
          }
          if (Character.isJavaIdentifierStart((char) c)) {
            fBuffer.setLength(0);
            do {
              fBuffer.append((char) c);
              c = read();
            } while (Character.isJavaIdentifierPart((char) c));
            unread(c);
            Integer i = (Integer) fgKeys.get(fBuffer.toString());
            if (i != null)
              return i.intValue();
            return WORD;
          }
          return OTHER;
        }
      }
    }

    /**
     * Returns next character.
     */
    protected int read() {
      if (fPos <= fEnd) {
        return fDoc.charAt(fPos++);
      }
      return EOF;
    }

    public void setRange(String text) {
      fDoc = text;
      fPos = 0;
      fEnd = fDoc.length() - 1;
    }

    protected void unread(int c) {
      if (c != EOF)
        fPos--;
    }
  }

}


           
       








Related examples in the same category

1.SWT Text Editor DemoSWT Text Editor Demo
2.SWT Completion Editor
3.Basic Editor 2Basic Editor 2
4.Basic EditorBasic Editor
5.Basic Editor 3Basic Editor 3
6.Script MultiTextEdit
7.SWT Editor