Java Tutorial/Intermediate GUIs/Writing a simple editor

From Wikiversity
Jump to navigation Jump to search

Writing a simple editor[edit | edit source]

Writing a simple editor is a good exercise to learn some of the details of a widget toolkit. This editor uses JTextPane as the editor but apparently the DefaultStyledDocument requires a buffer that has not been implemented yet, so you will have to start writing this editor by implementing a buffer class. You have to consider the Position interface and the UndoableEdit may require a bit of thought, but the buffer itself is also not entirely trivial.

Exercises[edit | edit source]

  • Fill in the auto-generated method stubs (the class BufferContent is a gap).
  • Improve your editor with a JMenuBar
  • Add optional display of line numbers and bookmarks.
  • Add syntax highlighting for Java using an ANTLR parser.
  • Add code folding for sections of code (e.g. methods, blocks and inner classes). The following method does iterate over sections (subclasses of Element) of an AbstractDocument. Can these sections be useful for code folding?
Element element = textPane.getDocument ().getDefaultRootElement ();
printElements (element, 0);

private void printElements (Element element, int indent) {
    int len = element.getElementCount ();
    for (int i=0; i<len; i++) {    
        for (int j=0; j<indent; j++) {
	    System.out.print ("\t");
        }
        System.out.println (element.getName () + " (" + element.getStartOffset () + "-" + element.getEndOffset () + ") [" + element.getClass ().getSimpleName () + "]");
	printElements (element.getElement (i), indent+1);
    }
}

Source code[edit | edit source]

package org.wikiversity.java_tutorial;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Position;
import javax.swing.text.Segment;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleContext;
import javax.swing.text.AbstractDocument.Content;
import javax.swing.undo.UndoableEdit;

public class Editor
{
	private JScrollPane scrollPane;
	private JTextPane textPane;
	private JFrame frame;
	private AbstractDocument.Content content;

	public final static String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
	
	public class BufferContent implements Content
	{
		@Override
		public Position createPosition(int arg0) throws BadLocationException {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public void getChars(int arg0, int arg1, Segment arg2)
				throws BadLocationException {
			// TODO Auto-generated method stub
			
		}

		@Override
		public String getString(int arg0, int arg1) throws BadLocationException {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public UndoableEdit insertString(int arg0, String arg1)
				throws BadLocationException {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public int length() {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public UndoableEdit remove(int arg0, int arg1)
				throws BadLocationException {
			// TODO Auto-generated method stub
			return null;
		}	
	}

	public static void main (String[] args)
	{
		new Editor ().run (args);
	}

	public void run (String[] args)
	{
		frame = new JFrame ();
		textPane = new JTextPane ();
		scrollPane = new JScrollPane (textPane);
		scrollPane.setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		scrollPane.setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		frame.setLayout (new BorderLayout ());
		frame.add (scrollPane, BorderLayout.CENTER);
		frame.setSize (500, 500);
		frame.setVisible (true);
		content = new BufferContent ();
		StyleContext context = new StyleContext ();
		DefaultStyledDocument document = new DefaultStyledDocument (content, context);
		AttributeSet attributeSet = SimpleAttributeSet.EMPTY; 
		try {
			document.insertString (0, LOREM_IPSUM, attributeSet);
		}
		catch (BadLocationException ex) { /* that would be surprising in this context */ }
		textPane.setStyledDocument (document);
	}
}